我正在学习PIVOT函数,我想在数据库DDOT
中尝试使用它,我有用户在X年Y年以YYYYMM格式进行的事件(行)。
id_ev iddate id_user ...
------------------------
1 201901 321
2 201902 654
3 201903 987
4 201901 321
5 201903 987
我将查询基于MS Documentation,但没有收到错误,但无法用那些唯一事件(用户)的总和来填充它。简而言之,我想知道一年(y轴)中每个月(x轴)检查了多少用户(唯一)。但是,结果为NULL
YYYY jan feb mar
----------------------------
2019 NULL NULL NULL
我希望有一张我之前提到的完整表格。
YYYY jan feb mar
----------------------------
2019 2 1 1
在我尝试使用不同聚合函数的代码中,但是此块最接近SQL的结果。
CREATE TABLE ddot
(
id_ev int NOT NULL ,
iddate int NOT NULL ,
id_user int NOT NULL
);
INSERT INTO DDOT
(
[id_ev], [iddate], [id_user]
)
VALUES
(
1, 201901, 321
),
(
2, 201902, 654
),
(
3, 201903, 987
),
(
4, 201901, 321
),
(
5, 201903, 987
)
GO
SELECT *
FROM (
SELECT COUNT(DISTINCT id_user) [TOT],
DATENAME(YEAR, CAST(iddate+'01' AS DATETIME)) [YYYY], --concat iddate 01 to get full date
DATENAME(MONTH, CAST(iddate+'01' AS DATETIME)) [MMM]
FROM DDOT
GROUP BY DATENAME(YEAR, CAST(iddate+'01' AS DATETIME)),
DATENAME(MONTH, CAST(iddate+'01' AS DATETIME))
) AS DOT_COUNT
PIVOT(
SUM([TOT])
FOR MMM IN (jan, feb, mar)
) AS PVT
答案 0 :(得分:3)
理想情况下,您应该在iddate
列中使用实际日期,而不是字符串(数字?)。我们可以使用字符串函数来解决此问题:
SELECT
CONVERT(varchar(4), LEFT(iddate, 4)) AS YYYY,
COUNT(CASE WHEN CONVERT(varchar(2), RIGHT(iddate, 2)) = '01' THEN 1 END) AS jan,
COUNT(CASE WHEN CONVERT(varchar(2), RIGHT(iddate, 2)) = '02' THEN 1 END) AS feb,
COUNT(CASE WHEN CONVERT(varchar(2), RIGHT(iddate, 2)) = '03' THEN 1 END) AS mar,
...
FROM DDOT
GROUP BY
CONVERT(varchar(4), LEFT(iddate, 4));
请注意,如果iddate
列已经是文本,那么我们可以删除上面对CONVERT
的所有丑陋调用:
SELECT
LEFT(iddate, 4) AS YYYY,
COUNT(CASE WHEN RIGHT(iddate, 2) = '01' THEN 1 END) AS jan,
COUNT(CASE WHEN RIGHT(iddate, 2) = '02' THEN 1 END) AS feb,
COUNT(CASE WHEN RIGHT(iddate, 2) = '03' THEN 1 END) AS mar,
...
FROM DDOT
GROUP BY
LEFT(iddate, 4);