Поворот уникальных пользователей за каждый месяц, каждый год - PullRequest
1 голос
/ 25 апреля 2019

Я изучаю функцию PIVOT и хочу попробовать ее в своей БД, в таблице DDOT У меня есть события (строки), созданные пользователями в течение X месяца Y года в формате ГГГГММ.

id_ev iddate id_user ...
------------------------
1     201901 321
2     201902 654
3     201903 987
4     201901 321
5     201903 987

Я основываю свой запрос на MS Documentation , и я не получаю ошибок, но не могу заполнить его суммой этих уникальных событий (пользователей). Проще говоря, я хочу знать, сколько пользователей (уникальных) проверяли каждый месяц (ось X) в году (ось Y). Тем не менее, я получаю 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

1 Ответ

3 голосов
/ 25 апреля 2019

В идеале вы должны использовать фактическую дату в столбце 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...