我想根据一个常用商品选择所有销售订单商品。在下面的示例中,我想选择按项“面包”过滤的所有销售订单行。
数据集:
Order Items
10001 bread
10001 milk
10001 cheese
10001 apple
10001 milk
10002 cheese
10002 apple
10002 banana
10003 onions
10003 bread
10003 carrot
期望的输出:
10001 bread
10001 milk
10001 cheese
10001 apple
10001 milk
10003 onions
10003 bread
10003 carrot
结果不应包括中间订单,编号10002,因为它没有'面包'项目
我尝试使用EXISTS功能,但没有运气。
答案 0 :(得分:1)
使用嵌套的自联接:
SELECT a.Order, b.Item
FROM SalesOrder a
INNER JOIN (
SELECT Order
From SalesOrder
WHERE Item = 'bread'
) b
ON a.Order = b.Order
内部查询(b)获取包含面包项的所有ID。外部查询获取内部查询选择的每个ID的所有项。除非表中有多个行具有相同的ID和面包项(例如1, bread
和第二个1, bread
)DISTINCT
不是必需的,否则会降低性能。根据给出的有限信息,如果您的架构设计正确,则不应该有这样的数据(这意味着如果您的订单有两个面包项,它的数量= 2列,而不是两行'面包& #39 ;;如果它被设计为插入两行来表示同一项的数量2,那么你真的应该改变模式。)
如果您因某些原因不想要嵌套联接,可以这样做:
SELECT a.Order, a.Item
FROM SalesOrder a
WHERE EXISTS (
SELECT 1
From SalesOrder b
WHERE b.Item = 'bread'
AND b.Order = a.Order
)
你提到你试图使用EXISTS
但是没有让它发挥作用;这是怎么做的。几乎在所有情况下,WHERE EXISTS
和其他答案建议的WHERE IN
版本都会生成相同的计划(DISTINCT
仍然没有必要,但会产生影响)。它是可能的,但不太可能根据统计数据,索引等存在差异,但你不应该担心这一点。
无论您使用哪种查询,在Item
上设置索引都会加快速度(如果您没有这样的索引,是否应该添加这样的索引是一个完全独立的问题)。字符串比较扫描在SQL Server上并不是非常高效。
答案 1 :(得分:0)
在不知道确切的数据模型的情况下,您可能不得不最终做类似子查询的事情:
SELECT
SalesOrderLineID
, SalesOrderLineItem
FROM dbo.SalesOrderLines
WHERE SalesOrderLineID IN
(
SELECT DISTINCT
SalesOrderLineID
FROM dbo.SalesOrderLines
WHERE SalesOrderLineItem = 'Bread'
)
对于小型数据集,这是可以的,但如果它增长到数百万行,您将要查看查询并可能更改它。
答案 2 :(得分:0)
试试这个:
select SalesOrderLineID, SalesOrderLineItem FROM dbo.SalesOrderLines where SalesOrderLineID IN
(
select DISTINCT SalesOrderLineID FROM dbo.SalesOrderLines where SalesOrderLineItem = 'Bread'
)