从表A中选择不在表B中的每一行

时间:2019-07-19 13:53:18

标签: sql

我想比较两个表并从表A中获取所有不在表B中的记录。

这是一个例子

TableA
Articel ID                    
1                             
2                             
2                             
2                             
3                             
4                             
5                             
5

TableB
Articel ID                    
1                            
2                            
2
4                            
5                                                   

然后我想要拥有:

Articel ID                   
2                            
3                             
5                            

下面的代码不检查条目数,而只是忽略所有匹配的行,这样就可以了:

Articel ID
3
4 

这是我的查询

SELECT *
FROM TableA A
    LEFT JOIN TableB B ON A.ArticleID = B.ArticleID
WHERE B.ArticleID IS NULL

3 个答案:

答案 0 :(得分:3)

如果RDBMS支持EXCEPT ALL,则只需使用它就可以完成(Fiddle)。

SELECT "Articel ID"
FROM   TableA
EXCEPT ALL
SELECT "Articel ID"
FROM   TableB

否则,您可以应用ROW_NUMBER对行进行编号,然后使用EXCEPT(如果可用)(或其他任何进行反联接的方法,如果不可用)-db <> fiddle

SELECT "Articel ID"
FROM   (SELECT "Articel ID",
               ROW_NUMBER()
                 OVER (
                   PARTITION BY "Articel ID"
                   ORDER BY "Articel ID") AS RN
        FROM   TableA
        EXCEPT
        SELECT "Articel ID",
               ROW_NUMBER()
                 OVER (
                   PARTITION BY "Articel ID"
                   ORDER BY "Articel ID") AS RN
        FROM   TableB) T 

答案 1 :(得分:1)

这应该在POSTGRES中起作用,因为您需要在A中使用4个2,在B中使用两个2,才能在输出中得到2个:

SELECT
  ArticleID
FROM (
  SELECT
    TableA.ArticleID,
    ROW_NUMBER() OVER (PARTITION BY TableA.ArticleID) rowNo,
    COALESCE(t2.cnt, 0) rowsToAccept
  FROM
    TableA
  LEFT JOIN (
    SELECT
      ArticleID,
      COUNT(ArticleID) cnt 
    FROM
      TableB
    GROUP BY
      ArticleID
  ) t2
  ON TableA.ArticleID = t2.ArticleID
) t3
WHERE rowNo > rowsToAccept

答案 2 :(得分:0)

编辑:在两个表中都有唯一的列的情况下,将交换到更有效的解决方案中。

这是一个有趣的问题,这是我的快速解决方案可能会激发您的灵感。

SELECT
  TableA.ArticelID,
  COUNT(DISTINCT TableA.ID) - COUNT(DISTINCT TableB.ID) As tblDiff
FROM TableA
LEFT JOIN TableB ON TableA.ArticelID = TableB.ArticelID
GROUP BY TableA.ArticelID
HAVING tblDiff <> 0

它还会告诉您两者之间的区别,即一个或另一个缺少多少。对您的数据量不屑一顾,所以我并没有真正考虑提高效率。