简体   繁体   English

SQL 查询查找两个相关表之间的缺失行

[英]SQL Query to find missing rows between two related tables

I have two tables:我有两张桌子:

Table A表 A

  • ID ID
  • ABC_ID ABC_ID
  • VAL价值

Table B表 B

  • ID ID
  • ABC_ID ABC_ID
  • VAL价值

These two tables are directly related to each other through the ABC_ID column.这两个表通过ABC_ID列直接相互关联。

I want to find all the VAL column values in table A which are not present in table B for the same ABC_ID.我想在表 A 中找到所有VAL列值,这些值在表 B 中存在于相同的 ABC_ID。

SELECT A.ABC_ID, A.VAL FROM A WHERE NOT EXISTS 
   (SELECT * FROM B WHERE B.ABC_ID = A.ABC_ID AND B.VAL = A.VAL)

or

SELECT A.ABC_ID, A.VAL FROM A WHERE VAL NOT IN 
    (SELECT VAL FROM B WHERE B.ABC_ID = A.ABC_ID)

or

SELECT A.ABC_ID, A.VAL LEFT OUTER JOIN B 
    ON A.ABC_ID = B.ABC_ID AND A.VAL = B.VAL FROM A WHERE B.VAL IS NULL

Please note that these queries do not require that ABC_ID be in table B at all.请注意,这些查询根本不需要表 B 中的 ABC_ID。 I think that does what you want.我认为这就是你想要的。

Another solution based on JOIN .另一种基于JOIN的解决方案。
Join combines content from table A and table B using a link, the ON part of the request. Join 使用链接(请求的ON部分)组合表 A 和表 B 中的内容。

SELECT
    *
FROM
    A
INNER JOIN
    B
ON
    B.ABC_ID = A.ABC_ID
WHERE
    B.VAL <> A.VAL

Basically we are combining table A with table B on ABC_ID and then checking where A.VAL is not equal to B.VAL.基本上,我们在 ABC_ID 上将表 A 与表 B 组合在一起,然后检查 A.VAL 不等于 B.VAL 的位置。 The joined data with INNER JOIN only contains records where both table A and B have ABC_ID present ().使用INNER JOIN连接的数据仅包含表 A 和 B 都存在 ABC_ID () 的记录。

DECLARE @start_date DATETIME= '04-01-2021'; DECLARE @start_date DATETIME='04-01-2021'; DECLARE @End_date DATETIME= '04-30-2021'; DECLARE @End_date DATETIME='04-30-2021'; declare @min int declare @max int select @min =min(test_uid), @max =max(test_uid) from test where DATE >= @START_DATE AND DATE < DATEADD(DAY, 1, @END_DATE)声明 @min int 声明 @max int select @min =min(test_uid), @max =max(test_uid) from test where DATE >= @START_DATE AND DATE < DATEADD(DAY, 1, @END_DATE)

select test_UID+1 as FirstMissingId, nextid - 1 as LastMissingId into #tmp from (select test.*,lead(test_UID) over (order by test_UID) as nextid from test where test_UID between @min and @max ) test where nextid <> test_UID+1 CREATE TABLE #tmp1 ( ID INT ) go select test_UID+1 as FirstMissingId, nextid - 1 as LastMissingId into #tmp from (select test.*,lead(test_UID) over (order by test_UID) as nextid from test where test_UID between @min and @max ) test where nextid <> test_UID+1 CREATE TABLE #tmp1 (ID INT) 去
declare @lastmissingid BIGINT , @firstmissingid BIGINT declare recscan cursor for select firstmissingid ,lastmissingid from #tmp open recscan fetch next from recscan into @firstmissingid ,@lastmissingid while @@FETCH_STATUS = 0 begin declare @maxcnt int = @lastmissingid声明 @lastmissingid BIGINT , @firstmissingid BIGINT 声明 recscan 游标选择 firstmissingid ,lastmissingid from #tmp open recscan fetch next from recscan 到 @firstmissingid ,@lastmissingid while @@FETCH_STATUS = 0 begin declare @maxcnt int = @lastmissingid
declare @mincnt, int =@firstmissingid声明@mincnt, int =@firstmissingid

WHILE @Counter <= @maxcnt同时@Counter <= @maxcnt
BEGIN INSERT #tmp1 values(@Counter) SET @Counter += 1 END fetch next from recscan into @firstmissingid ,@lastmissingid end close recscan deallocate recscan BEGIN INSERT #tmp1 values(@Counter) SET @Counter += 1 END 从recscan 取下一个到@firstmissingid ,@lastmissingid end close recscan 解除分配recscan

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

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