sql - 表列之间的一对多关系。分组和查找组合

标签 sql sql-server database tsql

在示例表 t0 中:

OrderID | ProductID
 0001      1254
 0001      1252
 0002      0038
 0003      1254
 0003      1252
 0003      1432
 0004      0038
 0004      1254
 0004      1252  

我需要找到一个 OrderID 下两个 ProductID 的最流行组合。目的是确定哪些产品更有可能在一个订单中一起销售,例如电话 - 免提。我认为逻辑是按 OrderID 分组,计算 productID 对的所有可能组合,按 OrderID 计算它们并选择前 2 个,但我真的不知道它是否可行。

最佳答案

可以使用“自连接”,但要确保其中一个产品 ID 大于另一个,以便我们在每个订单中获得“成对”产品。那么数数就简单了:

Demo

CREATE TABLE OrderDetail
    ([OrderID] int, [ProductID] int)
;

INSERT INTO OrderDetail
    ([OrderID], [ProductID])
VALUES
    (0001, 1254), (0001, 1252), (0002, 0038), (0003, 1254), (0003, 1252), (0003, 1432), (0004, 0038), (0004, 1254), (0004, 1252)
;

查询 1:

select -- top(2)
      od1.ProductID, od2.ProductID, count(*) count_of
from OrderDetail od1
inner join OrderDetail od2 on od1.OrderID = od2.OrderID and od2.ProductID > od1.ProductID
group by
      od1.ProductID, od2.ProductID
order by
      count_of DESC

Results :

| ProductID | ProductID | count_of |
|-----------|-----------|----------|
|      1252 |      1254 |        3 |
|      1252 |      1432 |        1 |
|      1254 |      1432 |        1 |
|        38 |      1252 |        1 |
|        38 |      1254 |        1 |

----

关于显示“前 2 名”或其他内容。您可能会获得“同等最高”的结果,因此我建议您需要使用 dense_rank() 并且您甚至可能想要“逆向”结果,以便您拥有一列 productids 及其相关联秩。您执行此操作和/或存储此操作的频率由您决定。

with ProductPairs as (
      select 
             p1, p2, count_pair
          , dense_rank() over(order by count_pair DESC) as ranked
      from (
            select
                  od1.ProductID p1, od2.ProductID p2, count(*) count_pair
            from OrderDetail od1
            inner join OrderDetail od2 on od1.OrderID = od2.OrderID and od2.ProductID > od1.ProductID
            group by
                  od1.ProductID, od2.ProductID
            ) d
      )
, RankedProducts as (
       select p1 as ProductID, ranked, count_pair
       from ProductPairs
       union all
       select p2 as ProductID, ranked, count_pair
       from ProductPairs
       )
select *
from RankedProducts
where ranked <= 2
order by ranked, ProductID

关于sql - 表列之间的一对多关系。分组和查找组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47423273/

相关文章:

sql - 选择列名称中包含句点的列 SQL Server

java - 如何使用 JPA 将 Servlet 中的 BLOB 存储在数据库中

php - 上传文件后更新数据库的问题

sql - Oracle:将(合并)一些计数到单行上?

c# - SQL 中的字符串函数而不是 C#

SQL 选择不同的列

php - 按月自动生成发票的解决方案?

mySQL 查询 : for a given typeId, 获取所有条目及其answerCount

sql-server - 如何设置模式比较文件,以便它始终忽略特定的数据库模式?

sql-server - 创建表时的条件