Sql 从子表中选择不在另一个表中且父表没有其他子表的记录

Sql 从子表中选择不在另一个表中且父表没有其他子表的记录,sql,sql-server,tsql,sql-server-2008-r2,Sql,Sql Server,Tsql,Sql Server 2008 R2,我试图编写一个查询来选择子表中的所有孤立记录,但仅当孤立记录是表中的唯一项时 我有两个来自不同系统的独立数据库,因此无法使用外键强制引用完整性约束。以下是每种方法的简单模式: ITEMS Order | Item ---------------- 1 | A1 1 | A2 2 | A1 COMP Item ------- A2 以上面的数据为例,我想要一个返回Order 2的查询,因为父级上唯一可用的项已被删除 到目前为止,我有下面的查询,它为

我试图编写一个查询来选择子表中的所有孤立记录,但仅当孤立记录是表中的唯一项时

我有两个来自不同系统的独立数据库,因此无法使用外键强制引用完整性约束。以下是每种方法的简单模式:

ITEMS
Order  |  Item
----------------
1      |   A1
1      |   A2
2      |   A1

COMP
Item
-------
A2
以上面的数据为例,我想要一个返回Order 2的查询,因为父级上唯一可用的项已被删除

到目前为止,我有下面的查询,它为我返回所有孤立的记录,包括order 1

SELECT Order FROM Items as i LEFT JOIN Comp as c ON i.Item = c.Item WHERE c.Item IS NULL

有什么想法吗?

当我创建两个表并输入数据时,这里是查询和结果

CREATE TABLE Items(
  [Order] int,
  Item varchar(50)
);

CREATE TABLE Comp(
  Item varchar(50)
);

INSERT Items ([Order],Item)
VALUES (1, 'A1');
INSERT Items ([Order],Item)
VALUES (1, 'A2');
INSERT Items ([Order],Item)
VALUES (2, 'A1');

INSERT Comp (Item)
VALUES('A2');




SELECT i.[Order], i.Item 
FROM Items as i 
LEFT JOIN Comp as c ON i.Item = c.Item 
WHERE c.Item IS NULL

Order   Item
1       A1
2       A1

当我创建两个表并输入数据时,下面是查询和结果

CREATE TABLE Items(
  [Order] int,
  Item varchar(50)
);

CREATE TABLE Comp(
  Item varchar(50)
);

INSERT Items ([Order],Item)
VALUES (1, 'A1');
INSERT Items ([Order],Item)
VALUES (1, 'A2');
INSERT Items ([Order],Item)
VALUES (2, 'A1');

INSERT Comp (Item)
VALUES('A2');




SELECT i.[Order], i.Item 
FROM Items as i 
LEFT JOIN Comp as c ON i.Item = c.Item 
WHERE c.Item IS NULL

Order   Item
1       A1
2       A1

如果您
按[Order]
具有count(distinct[Item])=1的条件下对表
项进行分组
,则只需1项即可获得所有订单。
然后使用
notexists
检查这些订单是否存在于
COMP
中,或者使用类似查询的左连接:

select i.[Order] from ITEMS i
where i.[Order] IN (
  select [Order] from ITEMS
  group by [Order]
  having count(distinct [Item]) = 1
)
and not exists (select 1 from COMP where [Item] = i.[Item])
或:


如果您
按[订单]分组
项目
具有计数(不同的[项目])=1的条件下,请参见。

,您只需1个项目即可获得所有订单。
然后使用
notexists
检查这些订单是否存在于
COMP
中,或者使用类似查询的左连接:

select i.[Order] from ITEMS i
where i.[Order] IN (
  select [Order] from ITEMS
  group by [Order]
  having count(distinct [Item]) = 1
)
and not exists (select 1 from COMP where [Item] = i.[Item])
或:


请参见。

您的查询就在这里:

SELECT i.Order 
FROM 
  Items as i 
  LEFT JOIN Comp as c 
  ON i.Item = c.Item 
GROUP BY i.Order
HAVING COUNT(c.Item) = 0
此查询查找与订单相关的每个c.项均为空的所有订单

离开后,加入您的数据如下所示:

i.Order | i.Item | c.Item
1       |   A1   |  null
1       |   A2   |  A2
2       |   A1   |  null
分组和计数c.项目给出

i.Order | i.Item | COUNT(c.Item)
1       |   A1   |  1
2       |   A1   |  0
因为计数是递增的,所以对于空值,步长为0,对于任何非空值,增量为1

我们想要i.Order=2行,这是have给我们的;HAVING是在分组完成后应用的where子句。(其中子句在分组前应用,不能用于分组)


因此,此查询将查找其所有
c.Item
s为空的每个订单

SELECT i.Order 
FROM 
  Items as i 
  LEFT JOIN Comp as c 
  ON i.Item = c.Item 
GROUP BY i.Order
HAVING COUNT(c.Item) = 0
此查询查找与订单相关的每个c.项均为空的所有订单

离开后,加入您的数据如下所示:

i.Order | i.Item | c.Item
1       |   A1   |  null
1       |   A2   |  A2
2       |   A1   |  null
分组和计数c.项目给出

i.Order | i.Item | COUNT(c.Item)
1       |   A1   |  1
2       |   A1   |  0
因为计数是递增的,所以对于空值,步长为0,对于任何非空值,增量为1

我们想要i.Order=2行,这是have给我们的;HAVING是在分组完成后应用的where子句。(其中子句在分组前应用,不能用于分组)


因此,此查询将查找OP中所有
c.Item
s为空的每个订单:“以上述数据为例,我希望查询返回订单2,因为父项上唯一可用的项目已被删除。”订单1不应包含在结果中,因为其至少有一个项目位于
Comp
中。OP中写道:“以上述数据为例,我希望查询返回订单2,因为父项上唯一可用的项目已被删除。”订单1不应包含在结果中,因为其至少有一项在
Comp
中。这是一个很好的解决方案!我考虑过使用聚合,但忘记了空值不起作用!谢谢伟大的解决方案!我考虑过使用聚合,但忘记了空值不起作用!谢谢