自连接或递归查询以获取计数

Self join or Recursive query to get the count

我需要按行分组,其中分组集中的一个值存在于另一行中。就像我有下面的 table

 | OrderID | ProductID |
 | 123     |    A      |
 | 123     |    B      |
 | 223     |    B      |
 | 223     |    C      |
 | 323     |    C      |
 | 323     |    D      |
 | 423     |    E      |

我需要以下内容。我一直在想一些方法,但无法到达任何地方。有什么帮助吗?

 |ProductId | NoOfOrders |
 | A|B|C|D  |     3      |
 |    E     |     1      |

给你。这从基于匹配产品的简单分组开始,然后使用循环递归地将事物分组在一起,直到它找不到更多的合并来做:

CREATE TABLE #data 
(
    OrderId INT, 
    ProductId CHAR(1)
);

INSERT INTO #data (OrderId, ProductId)
VALUES (123,'A'),
(123,'B'),
(223,'B'),
(223,'C'),
(323,'C'),
(323,'D'),
(423,'E');

CREATE TABLE #data2
(
    OrderId INT, 
    ProductId CHAR(1),
    Grp INT
);

WITH cte AS
(
    SELECT OrderId,
           ProductId,
        DENSE_RANK() OVER (ORDER BY ProductId) r
    FROM #data
)
INSERT INTO #data2(OrderId, ProductId, Grp)
SELECT cte.OrderId,
    cte.ProductId,
    r
FROM cte

DECLARE @updates INT = 1;

WHILE @updates > 0
BEGIN
    -- join groups where there is a lower numbered group that it connects to
    UPDATE a
    SET Grp = b.Grp
    FROM #data2 a
    INNER JOIN #data2 b ON b.OrderId = a.OrderId
        OR b.ProductId = a.ProductId
    WHERE a.Grp > b.Grp

    -- end when we have done nothing this cycle
    SET @updates = @@ROWCOUNT
END

SELECT 
    STUFF((SELECT DISTINCT '|'+ ProductId                                  
            FROM   #data2 
            WHERE grp = o.grp 
            FOR xml path('')
            ), 1, 1, '') AS Products,
            COUNT(DISTINCT o.OrderId) AS NumOrders
FROM #data2 o
GROUP BY grp