如何编写SQL Server 2014查询语句统计商品同订单共同出现次数
统计商品在订单中共同出现次数的SQL查询方案
没问题!我来帮你搞定这个统计商品共同出现次数的需求,完全适配SQL Server 2014版本~
首先我先默认你的表结构关联逻辑是这样的(如果实际字段名有差异,你替换成自己的就行):
ORDERS表:包含订单主键(比如OrderID)ORDERS_ITEMS表:关联订单和商品,字段包括OrderID(关联ORDERS)、ItemID(关联ITEMS)ITEMS表:商品信息,主键ItemID,还有商品名称ItemName之类的描述字段
下面给你两种实用的查询方案,你可以根据自己的数据量和需求选择:
方案一:用子查询筛选目标订单后统计
这种方法逻辑直观,适合新手理解:
-- 先定义你要查询的特定商品ID,替换成实际值 DECLARE @TargetItemID INT = 123; SELECT i.ItemID, i.ItemName, COUNT(DISTINCT oi.OrderID) AS CoOccurrenceCount FROM ORDERS_ITEMS oi JOIN ITEMS i ON oi.ItemID = i.ItemID WHERE -- 只保留包含目标商品的订单 oi.OrderID IN ( SELECT OrderID FROM ORDERS_ITEMS WHERE ItemID = @TargetItemID ) -- 排除目标商品本身,只统计其他商品 AND oi.ItemID != @TargetItemID GROUP BY i.ItemID, i.ItemName -- 按共同出现次数从多到少排序,方便看最热门的搭配 ORDER BY CoOccurrenceCount DESC;
逻辑解释:
- 子查询先找出所有包含目标商品的订单ID
- 关联
ORDERS_ITEMS和ITEMS表,筛选出这些订单里的所有其他商品 COUNT(DISTINCT oi.OrderID)确保每个订单只被统计一次(避免同一订单里同一商品多次下单导致重复计数,这也是业务上最常用的统计逻辑)
方案二:用自连接提升查询效率
如果你的订单数据量很大,这种自连接的方法通常比子查询效率更高,尤其是当ORDERS_ITEMS表有OrderID+ItemID的复合索引时:
DECLARE @TargetItemID INT = 123; SELECT other_i.ItemID, other_i.ItemName, COUNT(DISTINCT oi.OrderID) AS CoOccurrenceCount FROM ORDERS_ITEMS oi -- 自连接ORDERS_ITEMS,匹配同一订单里的其他商品 JOIN ORDERS_ITEMS other_oi ON oi.OrderID = other_oi.OrderID JOIN ITEMS other_i ON other_oi.ItemID = other_i.ItemID WHERE -- 锁定目标商品的订单记录 oi.ItemID = @TargetItemID -- 排除目标商品本身 AND other_oi.ItemID != @TargetItemID GROUP BY other_i.ItemID, other_i.ItemName ORDER BY CoOccurrenceCount DESC;
逻辑解释:
- 把
ORDERS_ITEMS表和自己连接,关联条件是同一订单ID - 一边筛选出目标商品的记录,另一边匹配同订单的其他商品
- 同样用
COUNT(DISTINCT)保证按订单数统计,避免重复计数
额外注意事项:
- 如果你的业务需求是统计“商品共同出现的行数”(比如同一订单里某商品买了2次就算2次),那可以去掉
DISTINCT,直接用COUNT(oi.OrderID) - 建议给
ORDERS_ITEMS表的OrderID和ItemID字段创建复合索引,能大幅提升查询速度 - 如果你的表字段名和我假设的不一样(比如
ORDERS_ITEMS里叫ProductID而不是ItemID),记得替换成实际的字段名
内容的提问来源于stack exchange,提问作者jpenn




