我如何通过一个共同项目为每个销售订单选择完整的行集?

时间:2015-03-26 06:36:58

标签: sql sql-server tsql

我想根据一个常用商品选择所有销售订单商品。在下面的示例中,我想选择按项“面包”过滤的所有销售订单行。

数据集:

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功能,但没有运气。

3 个答案:

答案 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, breadDISTINCT不是必需的,否则会降低性能。根据给出的有限信息,如果您的架构设计正确,则不应该有这样的数据(这意味着如果您的订单有两个面包项,它的数量= 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'
)