我一直在寻找这个,但没有找到任何特别的东西。
是否可以使用一个像ALL IN一样的SQL查询?为了更好地解释,这是一个表结构。
Orders table
OrderItem table (having several columns, but mainly ProductID, OrderID)
ProductGroup table (several columns, but mainly GroupID and ProductID)
我想编写一个查询,它将选择属于特定ProductGroup的所有订单。所以,如果我有一个名为" XYZ" ID = 10。它有一个ProductID。说ProductID01
订单包含两个订单商品。 ProductID01和ProductID02。要查找特定产品组中的所有订单,我可以使用简单的SQL,如
SELECT bvc_OrderItem.ProductID, bvc_OrderItem.OrderID
From bvc_OrderItem
INNER JOIN bvc_Product_Group_Product with (nolock) ON bvc_OrderItem.ProductID = bvc_Product_Group_Product.ProductID
WHERE bvc_Product_Group_Product.GroupID = 10
或者我可以使用IN Clause编写
SELECT bvc_OrderItem.ProductID, bvc_OrderItem.OrderID
From bvc_OrderItem
WHERE ProductID IN (
SELECT ProductID FROM bvc_Product_Group_Product WHERE GroupID=10
)
但是,这将返回一个或多个ProductID属于产品组的所有订单。如果所有订单商品都是产品组的一部分,我需要返回订单行
所以基本上,我需要一个IN子句,如果IN子句中的所有值都与bvc_OrderItem中的行匹配,则认为是匹配的。
或者如果我们使用Join,那么只有当左侧的所有行在相应的右表中都有值时,才能成功加入。
如果我能更简单地写它,我会像这样写
Select ID FROM Table WHERE ID IN (1, 2, 3, 4)
如果表包含所有带有id 1,2,3,4的行;它应该回归成功。如果缺少任何这些IN值,它应该返回false并且不应该选择任何内容。
你认为有可能吗?或者有一种解决方法可以做到这一点?
答案 0 :(得分:3)
您可以通过多种方式获取订单列表,例如:
SELECT oi.OrderID
FROM bvc_OrderItem oi JOIN
bvc_Product_Group_Product pgp
ON oi.ProductID = pgp.ProductId AND
pgp.GroupID = 10
GROUP BY oi.OrderID
HAVING COUNT(DISTINCT oi.ProductID) = (SELECT COUNT(*)
FROM bvc_Product_Group_Product
WHERE GroupID = 10
);
获取特定产品需要额外join
。在大多数情况下,订单列表更有用。
ALL IN
语法的问题在于它没有做你想做的事。您想要选择订单。语法:
SELECT bvc_OrderItem.ProductID, bvc_OrderItem.OrderID
From bvc_OrderItem
WHERE ProductID ALL IN (SELECT ProductID
FROM bvc_Product_Group_Product
WHERE GroupID = 10
)
这并未指定您打算将分组设为OrderId
,而不是其他某个级别。
但更基本的是,SQL语言的灵感来自关系代数。 SELECT
,JOIN
,WHERE
和GROUP BY
的结构与关系代数基本结构直接相关。 ALL IN
的概念 - 尽管有时很有用 - 可以使用更基本的构建块来表达。
答案 1 :(得分:0)
你可以通过这个棘手的声明来做到这一点:
DECLARE @Items TABLE
(
OrderID INT ,
ProductID INT
)
DECLARE @Groups TABLE
(
ProductID INT ,
GroupID INT
)
INSERT INTO @Items
VALUES ( 1, 1 ),
( 1, 2 ),
( 2, 1 ),
( 3, 3 ),
( 3, 4 )
INSERT INTO @Groups
VALUES ( 1, 10 ),
( 2, 10 ),
( 3, 10 ),
( 4, 15 )
SELECT OrderID
FROM @Items i
GROUP BY OrderID
HAVING ( CASE WHEN 10 = ALL ( SELECT gg.GroupID
FROM @Items ii
JOIN @Groups gg ON gg.ProductID = ii.ProductID
WHERE ii.OrderID = i.OrderID ) THEN 1
ELSE 0
END ) = 1
输出:
OrderID
1
2
另外(这是更好的):
SELECT OrderID
FROM @Items i
JOIN @Groups g ON g.ProductID = i.ProductID
GROUP BY OrderID
HAVING MIN(g.GroupID) = 10
AND MAX(g.GroupID) = 10