3

我一直在使用

SELECT
    Author,
    ISNULL(MAX(CASE Status WHEN 'Duplicate' THEN NumDocs END),'') AS Duplicate,
    ISNULL(MAX(CASE Status WHEN 'Failure' THEN NumDocs END),'') AS Failure,
    ISNULL(MAX(CASE Status WHEN 'Rejected' THEN NumDocs END),'') AS Rejected,
    ISNULL(MAX(CASE Status WHEN 'Success' THEN NumDocs END),'') AS Success,
    ISNULL(MAX(CASE Status WHEN 'TOTAL' THEN NumDocs END),'') AS TOTAL
FROM    
    (SELECT
        CASE WHEN (GROUPING(Author)=1) THEN 'ALL'
            ELSE ISNULL(Author,'UNKNOWN') END AS Author,
        CASE WHEN (GROUPING(Status )=1) THEN 'TOTAL'
            ELSE ISNULL(Status ,'UNKNOWN') END AS [Status],
        COUNT(Status) AS NumDocs
    FROM 
        tbl_Document D
    LEFT JOIN
        tbl_Status S
            ON
                D.status_id = S.status_id   
    GROUP BY
        Author,
        Status
    WITH ROLLUP) BASE
GROUP BY 
    Author

改造:

[Author]  [Status]
Alan      SUCCESS
Bob       FAILURE
Bob       SUCCESS
Charles   SUCCESS
Dave      FAILURE
Dave      DUPLICATE

到:

[Author] [SUCCESS] [FAILURE] [DUPLICATE] [TOTALS]
Alan        1         0           0         1
Bob         1         1           0         2
Charles     1         0           0         1
Dave        0         1           1         2
TOTAL       3         2           1         6

我可以使用 PIVOT 语句接近此输出,但我不确定如何获取 TOTAL 行/列?

SELECT
  * 
FROM 
  (SELECT Author, status_id FROM tbl_Document) d
PIVOT
  (COUNT(status_id) FOR status_id IN ([1],[3],[5],[6])) p

给出:

[Author] [SUCCESS] [FAILURE] [DUPLICATE] 
Alan        1         0           0      
Bob         1         1           0      
Charles     1         0           0      
Dave        0         1           1     

我猜我需要将 ROLLUP 放入某个子查询中......?

4

1 回答 1

4

你没有发布表模式,所以我试图推断它。我从您提供的输入开始(请参阅最里面的评论SELECT),因此您应该能够使其适应您的实际模式。我在没有任何文档的情况下添加了一个额外的作者,因为我认为您希望在最终报告输出中看到这些作者。排除这些作者是微不足道的。

DECLARE @Status table
(
    Id int NOT NULL,
    Status nvarchar(50) NOT NULL
)

DECLARE @Authors table
(
    Id int NOT NULL,
    Name nvarchar(50) NOT NULL
)

DECLARE @Documents table
(
    Id int NOT NULL,
    AuthorId int NOT NULL,
    StatusId int NOT NULL
)

INSERT INTO @Status VALUES (1, 'Duplicate')
INSERT INTO @Status VALUES (2, 'Failure')
INSERT INTO @Status VALUES (3, 'Rejected')
INSERT INTO @Status VALUES (4, 'Success')

INSERT INTO @Authors VALUES (1, 'Alan')
INSERT INTO @Authors VALUES (2, 'Bob')
INSERT INTO @Authors VALUES (3, 'Charles')
INSERT INTO @Authors VALUES (4, 'Dave')
INSERT INTO @Authors VALUES (5, 'Tom') -- Test for authors without documents

INSERT INTO @Documents VALUES (1, 1, 4)
INSERT INTO @Documents VALUES (2, 2, 2)
INSERT INTO @Documents VALUES (3, 2, 4)
INSERT INTO @Documents VALUES (4, 3, 4)
INSERT INTO @Documents VALUES (5, 4, 2)
INSERT INTO @Documents VALUES (6, 4, 1)

SELECT
    (CASE WHEN GROUPING(Name) = 1 THEN 'Total' ELSE Name END) AS Author,
    SUM(Duplicate) AS Duplicate,
    SUM(Failure) AS Failure,
    SUM(Rejected) AS Rejected,
    SUM(Success) AS Success,
    SUM(Duplicate + Failure + Rejected + Success) AS Total
    FROM
    (
        SELECT
            Name,
            (CASE WHEN Status = 'Duplicate' THEN 1 ELSE 0 END) AS Duplicate,
            (CASE WHEN Status = 'Failure' THEN 1 ELSE 0 END) AS Failure,
            (CASE WHEN Status = 'Rejected' THEN 1 ELSE 0 END) AS Rejected,
            (CASE WHEN Status = 'Success' THEN 1 ELSE 0 END) AS Success
            FROM
            (
                -- Original input
                SELECT
                    a.Name,
                    s.Status
                    FROM @Authors a
                    LEFT OUTER JOIN @Documents d ON d.AuthorId = a.Id
                    LEFT OUTER JOIN @Status s ON d.StatusId = s.Id
            ) i
    ) j
    GROUP BY Name WITH ROLLUP

输出:

作者 重复 失败 拒绝 成功 总计
艾伦 0 0 0 1 1
鲍勃 0 1 0 1 2
查尔斯 0 0 0 1 1
戴夫 1 1 0 0 2
汤姆 0 0 0 0 0
总计 1 2 0 3 6
于 2010-11-13T17:15:30.400 回答