我的Oracle版本是11g,我有两个表,它们的结构是这样的
CREATE TABLE "WP_CLI_CARD_JF" (
"COM_MD_CODE" VARCHAR2(6 BYTE) NOT NULL,
"COM_DB_ID" VARCHAR2(5 BYTE) NOT NULL,
"CLI_CARD_JF_LIST_NO" VARCHAR2(20 BYTE) NOT NULL,
"CLI_CARD" VARCHAR2(10 BYTE) DEFAULT ' ' NOT NULL,
"CLI_CARD_JF_TYPE" VARCHAR2(2 BYTE) NOT NULL,
"CLI_CARD_JF_NUM" NUMBER(12,3) DEFAULT NULL,
"CLI_CARD_JF_DATE" DATE DEFAULT NULL,
"CLI_CARD_JF_MEMO" VARCHAR2(50 BYTE) DEFAULT NULL,
"CUR_NO" VARCHAR2(2 BYTE) DEFAULT NULL,
"CLI_CARD_JF_ZT" VARCHAR2(2 BYTE) DEFAULT '1' NOT NULL,
"PROD_NO" VARCHAR2(8 BYTE) NOT NULL,
"PROD_ADD" VARCHAR2(50 BYTE) NOT NULL,
"BATCH_NO" VARCHAR2(12 BYTE) NOT NULL,
"PROD_NUM" NUMBER(12,3) DEFAULT NULL,
"SELL_PRICE" NUMBER(10,2) DEFAULT NULL,
"STD_PRICE" NUMBER(10,2) DEFAULT NULL,
"CLI_CARD_JF_DATE_UP" DATE DEFAULT sysdate,
"UPLOADEDBYWEBAPI" CHAR(1 BYTE) DEFAULT NULL
)
CREATE TABLE "YW_JFXFJLB" (
"ID" NUMBER(9,0) NOT NULL,
"HYKH" VARCHAR2(255 BYTE),
"HYSJH" VARCHAR2(255 BYTE),
"HYMC" VARCHAR2(255 BYTE),
"RETURNCODE" NUMBER(9,0),
"CURRINDEX" NUMBER(9,0),
"PAGESCOUNT" NUMBER(9,0),
"TOTALRECORDSCOUNT" NUMBER(9,0),
"TOTALRECORDS" NUMBER(9,0),
"COMDBID" VARCHAR2(255 BYTE),
"CLICARDJFLISTNO" VARCHAR2(255 BYTE),
"CLICARD" VARCHAR2(255 BYTE),
"CLICARDJFTYPE" VARCHAR2(255 BYTE),
"CLICARDJFNUM" NUMBER(20,8),
"CLICARDJFDATE" VARCHAR2(255 BYTE),
"CLICARDJFMEMO" VARCHAR2(255 BYTE),
"CURNO" VARCHAR2(255 BYTE),
"PRODNO" VARCHAR2(255 BYTE),
"BATCHNO" VARCHAR2(255 BYTE),
"PRODADD" VARCHAR2(255 BYTE),
"PRODNAME" VARCHAR2(255 BYTE),
"MONAD" VARCHAR2(255 BYTE),
"PRODPZWH" VARCHAR2(255 BYTE),
"PRODMEMO" VARCHAR2(255 BYTE),
"PRODSIZE" VARCHAR2(255 BYTE),
"PRODNUM" NUMBER(20,8),
"SELLPRICE" NUMBER(20,8),
"STDPRICE" NUMBER(20,8),
"CLICARDJFDATEUP" VARCHAR2(255 BYTE),
"COMMDCODE" VARCHAR2(255 BYTE),
"COMJCNAME" VARCHAR2(255 BYTE),
"COMZIPNAME" VARCHAR2(255 BYTE),
"BEIZHU" VARCHAR2(255 BYTE),
"NAME" VARCHAR2(255 BYTE),
"CREATEBY" NUMBER(9,0),
"CREATED" DATE DEFAULT SYSDATE,
"UPDATED" DATE DEFAULT SYSDATE,
"UPDATEBY" NUMBER(9,0),
"ORGID" NUMBER(9,0),
"NOTE" VARCHAR2(255 BYTE)
)
我尝试为每个人插入一条记录
INSERT INTO "YW_JFXFJLB" VALUES ('3110632', NULL, NULL, NULL, '0', '16', '25', '484', '0', '01', '2016120501005', '9000000003', '1', '70', '20161205150855', NULL, '01', 'H0110050', '3344', 'loreal', NULL, NULL, NULL, NULL, NULL, '1', '70', '70', '20161205150855', '800000', 'hq', 'for test', NULL, NULL, '0', TO_DATE('2024-07-05 09:20:06', 'SYYYY-MM-DD HH24:MI:SS'), TO_DATE('2024-07-05 09:20:06', 'SYYYY-MM-DD HH24:MI:SS'), '0', '0', NULL);
INSERT INTO wp_cli_card_jf (com_md_code, com_db_id, cli_card_jf_list_no, cli_card, cli_card_jf_type, cli_card_jf_num, cli_card_jf_date, cli_card_jf_memo, cur_no, cli_card_jf_zt, prod_no, prod_add, batch_no, prod_num, sell_price, std_price, cli_card_jf_date_up, uploadedbywebapi) VALUES ('800000', '01', '2016120501005', '9000000003', '1', 70.000, TO_DATE('2016-12-05 15:03:40', 'YYYY-MM-DD HH24:MI:SS'), '', '01', '1', 'H0110050', 'loreal', '3344', 1.000, 70.00, 70.00, TO_DATE('2016-12-05 15:08:55', 'YYYY-MM-DD HH24:MI:SS'), NULL);
我尝试根据一些关键字段(如 com_md_code、prod_no、batch_no、prod_add 和 cli_card_jf_memo)查找两个表之间的差异,我使用了以下 SQL 语句:
SELECT b.*
FROM Yw_jfxfjlb b
LEFT JOIN WP_CLI_CARD_JF a
ON a.com_md_code = b.commdcode
AND NVL(trim(a.cli_card_jf_list_no),'') = NVL(trim(b.clicardjflistno),'')
AND NVL(trim(a.prod_no),'') = NVL(trim(b.prodno),'')
AND NVL(trim(a.batch_no), '') = NVL(trim(b.batchno), '')
AND NVL(trim(a.prod_add), '') = NVL(trim(b.prodadd), '')
AND NVL(trim(a.CLI_CARD_JF_MEMO), '') = NVL(trim(b.CLICARDJFMEMO), '')
WHERE a.com_md_code IS NULL and b.CLICARD='9000000003';
我希望它显示的记录中的字段 com_md_code、prod_no、batch_no、prod_add 和 cli_card_jf_memo 中的值在这两个表之间不完全相同,但结果恰恰相反,我不知道为什么我的 SQL 语句不起作用,有人可以指出我犯的错误吗?我很欣赏它
在 Oracle 中,
''
与 NULL
相同,因此 NVL(something, '')
与 NVL(something, NULL)
相同,可以简化为 something
。
因此:
SELECT b.*
FROM Yw_jfxfjlb b
LEFT JOIN WP_CLI_CARD_JF a
ON a.com_md_code = b.commdcode
AND NVL(trim(a.cli_card_jf_list_no),'') = NVL(trim(b.clicardjflistno),'')
AND NVL(trim(a.prod_no),'') = NVL(trim(b.prodno),'')
AND NVL(trim(a.batch_no), '') = NVL(trim(b.batchno), '')
AND NVL(trim(a.prod_add), '') = NVL(trim(b.prodadd), '')
AND NVL(trim(a.CLI_CARD_JF_MEMO), '') = NVL(trim(b.CLICARDJFMEMO), '')
WHERE a.com_md_code IS NULL
AND b.CLICARD='9000000003';
相当于:
SELECT b.*
FROM Yw_jfxfjlb b
LEFT JOIN WP_CLI_CARD_JF a
ON a.com_md_code = b.commdcode
AND trim(a.cli_card_jf_list_no) = trim(b.clicardjflistno)
AND trim(a.prod_no) = trim(b.prodno)
AND trim(a.batch_no) = trim(b.batchno)
AND trim(a.prod_add) = trim(b.prodadd)
AND trim(a.CLI_CARD_JF_MEMO) = trim(b.CLICARDJFMEMO)
WHERE a.com_md_code IS NULL
AND b.CLICARD='9000000003';
如果任一修剪值只是空格或为
NULL
,则它将被评估为 NULL
并且比较 NULL = anything
永远不会为真,因此您的 JOIN
将与行不匹配。
您可能想要的是使用
NVL
(或 ANSI 标准 COALESCE
)和非空字符串,而不是 ''
,并确保非空字符串永远不会出现在您的数据中。由于您正在修剪前导和尾随空白,因此使用单个空格字符就可以了:
SELECT b.*
FROM Yw_jfxfjlb b
LEFT JOIN WP_CLI_CARD_JF a
ON a.com_md_code = b.commdcode
AND COALESCE(trim(a.cli_card_jf_list_no),' ') = COALESCE(trim(b.clicardjflistno),' ')
AND COALESCE(trim(a.prod_no),' ') = COALESCE(trim(b.prodno),' ')
AND COALESCE(trim(a.batch_no), ' ') = COALESCE(trim(b.batchno), ' ')
AND COALESCE(trim(a.prod_add), ' ') = COALESCE(trim(b.prodadd), ' ')
AND COALESCE(trim(a.CLI_CARD_JF_MEMO), ' ') = COALESCE(trim(b.CLICARDJFMEMO), ' ')
WHERE a.com_md_code IS NULL
AND b.CLICARD='9000000003';