为什么这个SQL语句不能根据某些关键字段查找两个表之间的差异

问题描述 投票:0回答:1

我的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 语句不起作用,有人可以指出我犯的错误吗?我很欣赏它

sql oracle11g
1个回答
0
投票

在 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';
© www.soinside.com 2019 - 2024. All rights reserved.