0

我试图找出某个项目在表中存在多少行,例如在下面的 itemID 1 示例中,我需要结果 5(不是 3,这是我目前得到的)。我很想将 TransactionID 添加到 PARTITION BY 子句中,但这会导致 Msg 8120,因为查询没有按 TransactionID 进行 GROUP。好吧,如果确实如此,那么获得该计数将很容易,但我不想在事务级别上进行分组。我该怎么做才能使 ItemCount 正确?这一定很容易,但我正在敲我的头。

DECLARE @t TABLE (TransactionID INT PRIMARY KEY IDENTITY, CustomerID INT, ItemID INT);

INSERT INTO @t (CustomerID, ItemID)
VALUES
    (1, 1),
    (2, 1),
    (3, 1),
    (4, 2),
    (1, 1),
    (2, 2),
    (3, 3),
    (4, 4),
    (1, 1);

SELECT
    CustomerID,
    ItemID,
    Rows = COUNT(*),
    ItemRowCount = COUNT(*) OVER (PARTITION BY ItemID)
FROM
    @t
GROUP BY
    CustomerID,
    ItemID
ORDER BY
    ItemID,
    CustomerID;

编辑:我想我是过度聚合了。Sebastian Meine 让我走上了正轨,他的回答是正确的,所以我接受了。但是,此子查询适用于我:

SELECT
    CustomerID,
    ItemID,
    Rows = COUNT(*),
    ItemRowCount = (SELECT COUNT(*) FROM @t x WHERE t.ItemID = x.ItemID)
FROM
    @t t
GROUP BY
    CustomerID,
    ItemID
ORDER BY
    ItemID,
    CustomerID;
4

4 回答 4

2

您需要通过查询将外部组数从实际组中提取出来。最简单的方法是这样的:

SQL小提琴

MS SQL Server 2008 架构设置

CREATE TABLE dbo.tbl  (TransactionID INT PRIMARY KEY IDENTITY, CustomerID INT, ItemID INT);

INSERT INTO dbo.tbl (CustomerID, ItemID)
VALUES
    (1, 1),
    (2, 1),
    (3, 1),
    (4, 2),
    (1, 1),
    (2, 2),
    (3, 3),
    (4, 4),
    (1, 1);

查询 1

SELECT *,SUM(Rows)OVER(PARTITION BY ItemId) ItemCnt
FROM(
SELECT
    CustomerID,
    ItemID,
    Rows = COUNT(*) 
FROM
    dbo.tbl
GROUP BY
    CustomerID,
    ItemID
)X
ORDER BY
    ItemID,
    CustomerID

结果

| CUSTOMERID | ITEMID | ROWS | ITEMCNT |
----------------------------------------
|          1 |      1 |    3 |       5 |
|          2 |      1 |    1 |       5 |
|          3 |      1 |    1 |       5 |
|          2 |      2 |    1 |       2 |
|          4 |      2 |    1 |       2 |
|          3 |      3 |    1 |       1 |
|          4 |      4 |    1 |       1 |

请注意,我将内部计数加在一起,而不是从头开始重新计数。

于 2013-08-09T15:12:47.607 回答
0

您可以使用 CTE 或加入子表(像这样)

SELECT
    tbl.CustomerID,
    tbl.ItemID,
    Rows = COUNT(*),
    ItemRowCount
FROM tbl
JOIN (SELECT ItemID, Count(*) as ItemRowCount
     FROM tbl
     GROUP BY ItemID) t ON tbl.ItemID = t.ItemID
GROUP BY
    tbl.CustomerID,
    tbl.ItemID,
    ItemRowCount
ORDER BY
    tbl.ItemID,
    CustomerID;

或这个

SELECT
    tbl.CustomerID,
    tbl.ItemID,
    Rows = COUNT(*),
    MAX(ItemRowCount)
FROM tbl
JOIN (SELECT ItemID, Count(*) as ItemRowCount
     FROM tbl
     GROUP BY ItemID) t ON tbl.ItemID = t.ItemID
GROUP BY
    tbl.CustomerID,
    tbl.ItemID
ORDER BY
    tbl.ItemID,
    CustomerID;
于 2013-08-09T15:03:48.693 回答
0

您可以使用简单的countand group by

SELECT
    ItemID,
    ItemRowCount = COUNT(1)
FROM
    @t
GROUP BY
    ItemID
ORDER BY
    ItemID

或者,如果您需要将总行数和项目行数附加到每一行:

SELECT
    CustomerID,
    ItemID,
    Rows = COUNT(1) over (),
    ItemRowCount = COUNT(1) OVER (PARTITION BY ItemID)
FROM
    @t
ORDER BY
    ItemID,
    CustomerID;
于 2013-08-09T15:03:53.340 回答
0

要找出某个项目在表中存在多少行,我们可能不需要 CustomerId。使用以下查询 -

DECLARE @t TABLE (TransactionID INT PRIMARY KEY IDENTITY, CustomerID INT, ItemID INT);

插入@t(客户 ID、项目 ID)
价值观
    (1, 1),
    (2, 1),
    (3, 1),
    (4, 2),
    (1, 1),
    (2, 2),
    (3, 3),
    (4, 4),
    (1, 1);

;与 cte AS(
    SELECT itemId, ROW_NUMBER() OVER (PARTITION BY itemId ORDER BY itemId DESC) AS row_cnt FROM @t
)   

SELECT itemId, MAX(row_cnt) row_count FROM cte GROUP BY itemId

它会回来——

itemId row_count
1 5
2 2
3 1
4 1

如果您需要customerId,则使用-

;与 cte AS(
    SELECT customerId, itemId, ROW_NUMBER() OVER (PARTITION BY itemId ORDER BY itemId DESC) AS row_cnt FROM @t
)   
SELECT customerId, itemId, MAX(row_cnt) item_count FROM cte GROUP BY CustomerID, itemId

它会回来——

customerId itemId item_count
1 1 5
2 1 2
3 1 3
2 2 1
4 2 2
3 3 1
4 4 1
于 2013-08-09T15:35:21.580 回答