SQL,检查行是否在另一个表中

时间:2015-05-21 09:44:08

标签: sql sql-server ssms

我有两个表,StockWarehouse

我需要获得所有仓库中可用的物品。

这是一个例子:

Stock Table:

ItemID        WarehouseID        ItemAmount
-------------------------------------------
1043               1                20
1043               2                2
1043               3                16
1043               4                17
1044               1                32
1044               2                12
1044               4                7
1055               2                6

Warehouse Table:

WarehouseID       WarehouseName
-------------------------------
1                 Name1
2                 Name2
3                 Name3
4                 Name4

对于示例,结果应该是项目1043,因为它在所有仓库中都可用,与其他仓库不同。

我没有找到解决方案,任何人都可以帮助我吗?

4 个答案:

答案 0 :(得分:5)

你也可以使用这个"双阴性"使用NOT EXISTS进行查询:

SELECT DISTINCT s.ItemID
FROM StockTable s
WHERE NOT EXISTS
(
    SELECT 1 FROM Warehouse w 
    WHERE NOT EXISTS(SELECT 1 FROM StockTable s2 
                     WHERE w.WarehouseID = s2.WarehouseID
                     AND   s.ItemID = s2.ItemID)
)

Demo fiddle

这种方法看起来更加冗长,但它有一些好处:

  • 如果规则越来越复杂,您可以轻松更改
  • 您可以删除DISTINCT以查看所有行
  • 您可以添加所有列,因为GROUP BY未使用
  • 它没有空值问题

答案 1 :(得分:3)

select itemid
from stock
group by itemid
having count(distinct warehouseid) = (select count(*) from warehouse);

SQLFiddle:http://sqlfiddle.com/#!15/e4273/1

如果股票表还可能包含金额= 0的项目,则需要添加where子句:

select itemid
from stock
where itemamount > 0
group by itemid
having count(distinct warehouseid) = (select count(*) from warehouse);

答案 2 :(得分:1)

NOT EXISTSEXCEPT结合使用:

select distinct ItemID
from stock s1
where not exists (select warehouseid from warehouse
                  except 
                  select warehouseid from stock s2 where s2.ItemID = s1.ItemID);

您甚至可以用select distinct ItemID替换select *来获取所有这些项目。

答案 3 :(得分:0)

我使用此查询:

SELECT 
    ItemID
FROM 
    stock
GROUP BY 
    ItemID
HAVING 
    SUM(DISTINCT warehouseid) = (SELECT SUM(WarehouseID) from warehouse)

这比使用COUNT更可靠,因为在极少数情况下不使用外键,它应该返回一些无效结果。