2016-11-03 52 views
0

我在Teradata 15.10.03.01中遇到以下问题。这是关于逗号分隔的列比较。考虑下面提到的数据和预期的结果。快速回复赞赏。提前致谢。TERADATA逗号分隔列比较

CREATE MULTISET TABLE TESTDB.TESTTABLE1 ,NO FALLBACK , 
     NO BEFORE JOURNAL, 
     NO AFTER JOURNAL, 
     CHECKSUM = DEFAULT, 
     DEFAULT MERGEBLOCKRATIO 
     (
      A VARCHAR(250) CHARACTER SET LATIN NOT CASESPECIFIC, 
      B VARCHAR(250) CHARACTER SET LATIN NOT CASESPECIFIC, 
      C VARCHAR(250) CHARACTER SET LATIN NOT CASESPECIFIC) 
    PRIMARY INDEX (A); 

    CREATE MULTISET TABLE TESTDB.TESTTABLE2 ,NO FALLBACK , 
     NO BEFORE JOURNAL, 
     NO AFTER JOURNAL, 
     CHECKSUM = DEFAULT, 
     DEFAULT MERGEBLOCKRATIO 
     (
      A VARCHAR(250) CHARACTER SET LATIN NOT CASESPECIFIC, 
      B VARCHAR(250) CHARACTER SET LATIN NOT CASESPECIFIC, 
      C VARCHAR(250) CHARACTER SET LATIN NOT CASESPECIFIC) 
    PRIMARY INDEX (A); 



    INSERT INTO TESTDB.TESTTABLE1 VALUES('A1','B1','C1'); 
    INSERT INTO TESTDB.TESTTABLE1 VALUES('A2','B2','C2'); 
    INSERT INTO TESTDB.TESTTABLE1 VALUES('A3',NULL,'C3'); 
    INSERT INTO TESTDB.TESTTABLE1 VALUES('A4',NULL,'C4'); 
    INSERT INTO TESTDB.TESTTABLE1 VALUES(NULL,'B5','C5'); 
    INSERT INTO TESTDB.TESTTABLE1 VALUES(NULL,'B6','C6'); 
    INSERT INTO TESTDB.TESTTABLE1 VALUES(NULL,NULL,'C7'); 
    INSERT INTO TESTDB.TESTTABLE1 VALUES(NULL,NULL,'C8'); 

    INSERT INTO TESTDB.TESTTABLE2 VALUES('A1','B1','C1'); 
    INSERT INTO TESTDB.TESTTABLE2 VALUES('A3',NULL,'C3'); 
    INSERT INTO TESTDB.TESTTABLE2 VALUES(NULL,'B5','C5'); 
    INSERT INTO TESTDB.TESTTABLE2 VALUES(NULL,NULL,'C7'); 

    SELECT * FROM TESTDB.TESTTABLE1; 

    A B  C 
    ------------- 
    A1 B1 C1 
    A2 B2 C2 
    A3   C3 
    A4   C4 
     B5 C5 
     B6 C6 
       C7 
       C8 

    SELECT * FROM TESTDB.TESTTABLE2;   
    A B  C 
    ------------  
    A1 B1 C1 
    A3   C3 
     B5 C5 
       C7 

预期的结果:

A B  C 
    ------------- 
    A2 B2 C2 
    A4   C3 
     B6 C6 

我试着用下面的查询,但它没有返回记录。

SELECT T1.A,T1.B,T1.C 
    FROM TESTDB.TESTTABLE1 T1 
    WHERE (T1.A,T1.B) 
    NOT IN 
    (
    SELECT T2.A,T2.B 
    FROM TESTDB.TESTTABLE2 T2 
    ) 
    ; 

任何机构请帮助框架查询?

解释为什么我的查询没有返回任何记录赞赏。

+0

凝聚你的空(大多数这个问题是作为一个整体的代码块中,'下面不滚动issue'不出来的。请花时间去的想法[如何提出一个好问题]。) – greybeard

回答

3

手册中有一些信息:Behavior of Nulls for NOT IN,但afaik根据标准SQL,此行为不正确。

您的查询应该不返回任何行,因为与NULL的结果为UNKNOWN的结果相比较,因此子查询返回的单个NULL将导致空结果。

因此,简单地按照每个DBMS的基本建议,从不使用NOT IN作为无效列

通常重写基于NOT EXISTS

SELECT T1.A,T1.B,T1.C 
FROM TESTDB.TESTTABLE1 T1 
WHERE NOT EXISTS 
(
SELECT * 
FROM TESTDB.TESTTABLE2 T2 
WHERE T1.A = T2.A 
    AND T1.B = T2.B 
) 
; 

但在你的情况,因为NULL不等于NULL这也将不会返回您预期的结果。

你需要一套操作,EXCEPT(或MINUS),它把空值等于:

SELECT * FROM TESTDB.TESTTABLE1 
EXCEPT 
SELECT * FROM TESTDB.TESTTABLE2 

编辑:

EXCEPT,因为它所有的三列进行比较,而不是可能无法提供正确的结果二,它正在为您的示例数据工作,但可能会失败您的真实数据。

有使用COALESCE(当然你需要选择这是保证不存在的值)从@DavidCram的solution,另一个是基于外部联接,但你需要的是在他第二个定义的NOT NULL列表:

SELECT T1.* 
FROM TESTDB.TESTTABLE1 T1 
LEFT JOIN TESTDB.TESTTABLE2 T2 
    ON (T1.A = T2.A OR (T1.A IS NULL AND T2.A IS NULL)) 
AND (T1.B = T2.B OR (T1.B IS NULL AND T2.B IS NULL)) 
WHERE T2.C IS NULL 
; 

这避免了COALESCE,可能还是加入一个主索引。

1

你需要的时候,你对它们进行比较

SELECT T1.A,T1.B,T1.C 
FROM TESTTABLE1 T1 
WHERE (COALESCE(T1.A,''),COALESCE(T1.B,'')) 
NOT IN 
(
SELECT COALESCE(T2.A,''),COALESCE(T2.B,'') 
FROM TESTTABLE2 T2 
) 
; 
+0

实际上,我更喜欢dnoeth的答案,但我会把它留在这里,因为它的工作原理是:-)。同样在你的预期结果中,我认为你说C3你的意思是C4(根据你的测试表中的实际情况) –

+0

事实上,我的答案可能不会工作,因为EXCEPT基于所有三列,而NOT IN是基于两个:) – dnoeth

+0

哦,你仍然从我这里得到一个赞成票,因为你的回答很清楚地解释了这些问题,我也不是使用“NOT IN”这种东西的粉丝 –