SQL Запрос: количество, группа по месяцам и годам с несколькими полями даты - PullRequest
0 голосов
/ 30 января 2020

У меня есть таблица, похожая на приведенную ниже, где все столбцы являются полями даты, в которых указывается дата определенного действия c. Допустим, есть 10 таких полей даты (только используя 10 полей даты в моем запросе / выводе)

---------------------------------------------------------
| Date_Event1 | Date_Event2 | Date_Event3 | Date_Event4 |
---------------------------------------------------------
| NULL        | NULL        | 2019-03-04  | NULL        |
| 2019-01-07  | 2019-03-04  | 2019-02-08  | 2019-02-15  |
| 2019-01-04  | NULL        | 2019-02-10  | NULL        |
| NULL        | 2019-01-10  | NULL        | 2019-01-11  |
| 2019-02-04  | NULL        | 2019-03-04  | NULL        |
| NULL        | 2019-02-04  | 2019-03-20  | NULL        |
| 2019-01-04  | NULL        | 2019-02-13  | 2019-03-22  |

Я пытаюсь получить вывод, который группирует все столбцы по месяцам и годам и считает число вхождений для каждого события Date_Event в каждом месяце-году, аналогичное приведенному ниже.

-----------------------------------------------------------------------
| Month-Year  | Date_Event1 | Date_Event2 | Date_Event3 | Date_Event4 |
-----------------------------------------------------------------------
| 01-2019     |      3      |      1      |     NULL    |      1      |
| 02-2019     |      1      |      1      |      3      |      1      |
| 03-2019     |     NULL    |      1      |      3      |      1      |

Не слишком много идей о том, с чего начать

Ответы [ 2 ]

0 голосов
/ 30 января 2020

Вы можете расширить это до нескольких столбцов

Для SQL Сервер :

with cte as 
(
select  NULL   as Date_Event1    , NULL  as Date_Event2    , '2019-03-04' as Date_Event3, NULL  as Date_Event4
union select '2019-01-07', '2019-03-04', '2019-02-08', '2019-02-15'
union select '2019-01-04', NULL      , '2019-02-10', NULL      
union select NULL       , '2019-01-10', NULL      , '2019-01-11'
union select '2019-02-04', NULL      , '2019-03-04', NULL      
union select NULL       , '2019-02-04', '2019-03-20', NULL      
union select '2019-01-04', NULL      , '2019-02-13', '2019-03-22'
),
yyyydd as
(
        select CONVERT(VARCHAR(7), Date_Event1, 126) as [Month-Year] from cte where Date_Event1 is not null
union   select CONVERT(VARCHAR(7), Date_Event2, 126) from cte where Date_Event2 is not null
union   select CONVERT(VARCHAR(7), Date_Event3, 126) from cte where Date_Event3 is not null
union   select CONVERT(VARCHAR(7), Date_Event4, 126) from cte where Date_Event4 is not null
)

    select [Month-Year] 
    , ( select sum(case when b.Date_Event1 is null then null else 1 end) from cte b where a.[Month-Year] = CONVERT(VARCHAR(7), b.Date_Event1, 126)  ) as Date_Event1 
    , ( select sum(case when b.Date_Event2 is null then null else 1 end) from cte b where a.[Month-Year] = CONVERT(VARCHAR(7), b.Date_Event2, 126)  ) as Date_Event1 
    , ( select sum(case when b.Date_Event3 is null then null else 1 end) from cte b where a.[Month-Year] = CONVERT(VARCHAR(7), b.Date_Event3, 126)  ) as Date_Event1 
    , ( select sum(case when b.Date_Event4 is null then null else 1 end) from cte b where a.[Month-Year] = CONVERT(VARCHAR(7), b.Date_Event4, 126)  ) as Date_Event1 
    from yyyydd a 
0 голосов
/ 30 января 2020

Вот пример, который будет выполнять подзапрос для каждого столбца.

SELECT RIGHT('0' + CAST(allDates.EventMonth AS CHAR(2)), 2) + '-' + CAST(allDates.EventYear AS CHAR(4)) AS [Month-Year],
    (SELECT COUNT(1) FROM EventTable WHERE DATEPART(YEAR, Date_Event1) = allDates.EventYear AND DATEPART(MONTH, Date_Event1) = allDates.EventMonth) AS Date_Event1,
    (SELECT COUNT(1) FROM EventTable WHERE DATEPART(YEAR, Date_Event2) = allDates.EventYear AND DATEPART(MONTH, Date_Event2) = allDates.EventMonth) AS Date_Event2,
    (SELECT COUNT(1) FROM EventTable WHERE DATEPART(YEAR, Date_Event3) = allDates.EventYear AND DATEPART(MONTH, Date_Event3) = allDates.EventMonth) AS Date_Event3,
    (SELECT COUNT(1) FROM EventTable WHERE DATEPART(YEAR, Date_Event4) = allDates.EventYear AND DATEPART(MONTH, Date_Event4) = allDates.EventMonth) AS Date_Event4
FROM (
    SELECT EventYear, EventMonth
    FROM (
        SELECT DATEPART(YEAR, Date_Event1) AS EventYear, DATEPART(MONTH, Date_Event1) AS EventMonth
        FROM EventTable
        UNION ALL
        SELECT DATEPART(YEAR, Date_Event2) AS EventYear, DATEPART(MONTH, Date_Event2) AS EventMonth
        FROM EventTable
        UNION ALL
        SELECT DATEPART(YEAR, Date_Event3) AS EventYear, DATEPART(MONTH, Date_Event3) AS EventMonth
        FROM EventTable
        UNION ALL
        SELECT DATEPART(YEAR, Date_Event4) AS EventYear, DATEPART(MONTH, Date_Event4) AS EventMonth
        FROM EventTable
        ) AS allDates
    GROUP BY EventYear, EventMonth
    ) AS allDates
ORDER BY allDates.EventYear, allDates.EventMonth

В этом примере используется INNER JOIN, но он может работать лучше в зависимости от размеров таблицы и индексов. et c.

SELECT RIGHT('0' + CAST(allDates.EventMonth AS CHAR(2)), 2) + '-' + CAST(allDates.EventYear AS CHAR(4)) AS [Month-Year],
    SUM(IIF(DATEPART(YEAR, e.Date_Event1) = allDates.EventYear AND DATEPART(MONTH, e.Date_Event1) = allDates.EventMonth, 1, 0)) AS Date_Event1,
    SUM(IIF(DATEPART(YEAR, e.Date_Event2) = allDates.EventYear AND DATEPART(MONTH, e.Date_Event2) = allDates.EventMonth, 1, 0)) AS Date_Event2,
    SUM(IIF(DATEPART(YEAR, e.Date_Event3) = allDates.EventYear AND DATEPART(MONTH, e.Date_Event3) = allDates.EventMonth, 1, 0)) AS Date_Event3,
    SUM(IIF(DATEPART(YEAR, e.Date_Event4) = allDates.EventYear AND DATEPART(MONTH, e.Date_Event4) = allDates.EventMonth, 1, 0)) AS Date_Event4,
FROM (
    SELECT EventYear, EventMonth
    FROM (
        SELECT DATEPART(YEAR, Date_Event1) AS EventYear, DATEPART(MONTH, Date_Event1) AS EventMonth
        FROM EventTable
        UNION ALL
        SELECT DATEPART(YEAR, Date_Event2) AS EventYear, DATEPART(MONTH, Date_Event2) AS EventMonth
        FROM EventTable
        UNION ALL
        SELECT DATEPART(YEAR, Date_Event3) AS EventYear, DATEPART(MONTH, Date_Event3) AS EventMonth
        FROM EventTable
        UNION ALL
        SELECT DATEPART(YEAR, Date_Event4) AS EventYear, DATEPART(MONTH, Date_Event4) AS EventMonth
        FROM EventTable
        ) AS allDates
    GROUP BY EventYear, EventMonth
    ) AS allDates
INNER JOIN EventTable AS e ON 1 = 1
GROUP BY allDates.EventYear, allDates.EventMonth
ORDER BY allDates.EventYear, allDates.EventMonth
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...