简体   繁体   English

DB2 SQL JOIN比较

[英]DB2 SQL Compare on JOIN

I have the following data: 我有以下数据:

TABLE1: 
ADDRESS               INTER1    INTER2
12345 E AVE STREET    44444     55555555
888 OtherStreet       44444     55555555


TABLE2: 
ADDRESS             INTER1  INTER2
12345 E AVE STREET  44444   55555555

I can probably resolve in code this way: 我大概可以这样解决代码:

if(tblOneInterOne == tblTwoInterOne ) {
   // compare address                                   
}

, but hoping to resolve in SQL. ,但希望在SQL中解决。

SELECT 
     A.ADDRESS
   , A.INTER1
   , A.INTER2
FROM TABLE1 AS A
    LEFT JOIN TABLE2 AS B
    ON A.INTER1 = B.INTER1
    AND A.INTER2 = B.INTER2
    AND A.ADDRESS <> B.ADDRESS

When comparing with the above SQL, I still get this address: 12345 E AVE STREET on my data result. 与上面的SQL进行比较时,我仍然得到此地址:12345 E AVE STREET在我的数据结果上。 I have also tried joining with a sub-query, i have also tried grouping, and ordering by asc. 我也尝试过使用子查询加入,也尝试过按asc进行分组和排序。 I am out of ideas. 我没主意。

Expected output : If selecting from TABLE1, match on first two integers, if match, then compare on address. 预期输出 :如果从TABLE1中进行选择,则匹配前两个整数,如果匹配,则在地址上进行比较。 If match, do not display. 如果匹配,则不显示。 If no match, then display non-match address. 如果不匹配,则显示不匹配的地址。 Vice-versa, if selecting from TABLE2, match on first two integers. 反之亦然,如果从TABLE2中选择,则匹配前两个整数。 If match, then compare on address, if no-match then the display should be null (no data). 如果匹配,则在地址上进行比较;如果不匹配,则显示应为空(无数据)。

Any help would be appreciated. 任何帮助,将不胜感激。

Thank you. 谢谢。

This query: 该查询:

SELECT A.ADDRESS, A.INTER1, A.INTER2
FROM TABLE1 A LEFT JOIN
     TABLE2 B
     ON A.INTER1 = B.INTER1 AND
        A.INTER2 = B.INTER2 AND
        A.ADDRESS <> B.ADDRESS;

is going to return all rows in A . 将返回A所有行。 That is what LEFT JOIN does. 这就是LEFT JOIN所做的。 That is what it is supposed to do. 那是应该做的。

If you want to filter rows from the first table, then change the JOIN type: 如果要过滤第一个表中的行,请更改JOIN类型:

SELECT A.ADDRESS, A.INTER1, A.INTER2
FROM TABLE1 A INNER JOIN
     TABLE2 B
     ON A.INTER1 = B.INTER1 AND
        A.INTER2 = B.INTER2 AND
        A.ADDRESS <> B.ADDRESS;

You can also then move the inequality condition to WHERE . 然后,您还可以将不等式条件移动到WHERE But using a LEFT JOIN and then moving the inequality to WHERE is rather ridiculous -- why specify an outer join and then undo it in the WHERE clause? 但是,使用LEFT JOIN然后将不等式移到WHERE是相当荒谬的-为什么要指定外部LEFT JOIN ,然后在WHERE子句中将其撤消?

The solution to this issue was the following: 该问题的解决方案如下:

SELECT 
     A.ADDRESS
   , A.INTER1
   , A.INTER2
FROM TABLE1 AS A
    INNER JOIN TABLE2 AS B
       ON A.INTER1 = B.INTER1
       AND A.INTER2 = B.INTER2
    LEFT JOIN TABLE2 AS B1
       ON B1.ADDRESS <> B.ADDRESS
WHERE A.ADDRESS <> B.ADDRESS
AND B1.ADDRESS IS NOT NULL

This allows to match on the first two integer values, then joins on the address. 这允许在前两个整数值上进行匹配,然后在地址上进行连接。 However, this causes records with multiple addresses to still display. 但是,这将导致仍显示具有多个地址的记录。 This is eliminated by the WHERE clause compare. 这可以通过WHERE子句比较来消除。

This was an actual production problem with provider data. 这是提供商数据的实际生产问题。 Once the solution is discovered, it seems extremely simple--but arriving to the solution is always the tricky part, right? 找到解决方案后,这似乎非常简单-但是到达解决方案始终是棘手的部分,对吧? I hope this helps someone else. 我希望这可以帮助其他人。

Edit 04/24/2016 编辑04/24/2016

After more quality testing, this solution needed additional clause, which was: 经过更多质量测试后,此解决方案需要附加条款,即:

SELECT 
     A.ADDRESS
   , A.INTER1
   , A.INTER2
FROM TABLE1 AS A
    INNER JOIN TABLE2 AS B
       ON A.INTER1 = B.INTER1
       AND A.INTER2 = B.INTER2
    LEFT JOIN TABLE2 AS B1
       ON B1.ADDRESS <> B.ADDRESS
WHERE NOT IN (SELECT B2.ADDRESS FROM TABLE2 AS B2 
                   INNER JOIN TABLE1 AS A2 
                     ON B2.INTER1 = A2.INTER1
                      AND B2.INTER2 = A2.INTER2)

 A.ADDRESS <> B.ADDRESS
AND B1.ADDRESS IS NOT NULL

Of course the 'WHERE NOT IN' allows the sub-query to exclude anything found. 当然,“ WHERE NOT IN”允许子查询排除找到的任何内容。 This can also be done using a CTE then excluding in the NOT IN clause. 也可以使用CTE然后在NOT IN子句中排除。 I hope this helps someone else. 我希望这可以帮助其他人。

try this : 尝试这个 :

SELECT 
        ifnull(f1.INTER1, f2.INTER1) as INTER1, 
        ifnull(f1.INTER2, f2.INTER2) as INTER2, 
        f1.ADDRESS as ADDRESS_A, f2.ADDRESS as ADDRESS_B,
        case 
        when f1.INTER1 then 'ADDRESS NOT IN TABLE1'
        when f2.INTER1 then 'ADDRESS NOT IN TABLE2'
        else 'ADDRESS ARE DIFFERENT' end as DIAGNOSTIC
FROM TABLE1 f1 
FULL OUTER JOIN TABLE2 f2 ON (f1.INTER1, f1.INTER2)  = (f2.INTER1, f2.INTER2)
where 
        f1.INTER1 is null or 
        f2.INTER1 is null or 
        f1.ADDRESS <> f2.ADDRESS;
--other solution if you want your result into multiple rows

select * from 
(
select ADDRESS, INTER1, INTER2 from table1
except
select ADDRESS, INTER1, INTER2 from table2
) tmp1

union all 

select * from 
(
select ADDRESS, INTER1, INTER2 from table2
except
select ADDRESS, INTER1, INTER2 from table1
) tmp2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM