在较高聚合级别上GROUP中的COUNT行数

时间:2013-08-09 15:01:04

标签: sql-server

我试图找出表格中存在多少行某个项目,例如在下面的itemID 1示例中,我需要结果5(不是3,这是我目前得到的)。我很想将TransactionID添加到PARTITION BY子句中,但这导致Msg 8120,因为查询不是GROUPID的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 个答案:

答案 0 :(得分:2)

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

SQL Fiddle

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

<强> Results

| 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 |

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

答案 1 :(得分: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;

答案 2 :(得分:0)

您可以使用简单的countgroup 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;

答案 3 :(得分:0)

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

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);

;WITH 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,使用 -

;WITH 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