Мера населения на несколько дат - PullRequest
0 голосов
/ 29 января 2019

Я хочу измерить численность населения нашей страны (которая состоит из нескольких мест).У меня есть две таблицы: мой первый набор данных - это таблица календаря со строкой для каждого первого дня каждого месяца.Моя вторая таблица содержит все люди, которые живут и жили в мануципализме.Что я хочу, так это численность населения каждого места в каждый первый день месяца из моей таблицы календарей.Ниже приведены некоторые необработанные данные (всего несколько записей таблицы персон, поскольку она содержит 100 000 записей)

Таблица календарей:

+----------+
|   Date   |
+----------+
| 1-1-2018 | 
+----------+
| 1-2-2018 | 
+----------+
| 1-3-2018 | 
+----------+
| 1-4-2018 | 
+----------+

Таблица персон

+-----+-----------+-----------+---------------+-------+
| BSN | Startdate |  Enddate  | Date of death | Place |
+-----+-----------+-----------+---------------+-------+
|  1  | 12-1-2000 |   null    |    null       |   A   |
+-----+-----------+-----------+---------------+-------+
|  2  | 10-5-2011 |   null    |    22-1-2018  |   B   |
+-----+-----------+-----------+---------------+-------+
|  3  | 16-12-2011| 10-2-2018 |    null       |   B   |
+-----+-----------+-----------+---------------+-------+
|  4  | 9-11-2012 |   null    |    null       |   B   |
+-----+-----------+-----------+---------------+-------+
|  5  | 8-9-2013  |   null    |    27-3-2018  |   A   |
+-----+-----------+-----------+---------------+-------+
|  6  | 7-10-2017 | 28-3-2018 |    null       |   B   |
+-----+-----------+-----------+---------------+-------+

Мой ожидаемый результат:

+----------+-------+------------+
|   Date   | Place | Population |
+----------+-------+------------+
| 1-1-2018 |   A   |     2      |
+----------+-------+------------+
| 1-1-2018 |   B   |     4      |
+----------+-------+------------+
| 1-2-2018 |   A   |     2      |
+----------+-------+------------+
| 1-2-2018 |   B   |     3      |
+----------+-------+------------+
| 1-3-2018 |   A   |     2      |
+----------+-------+------------+
| 1-3-2018 |   B   |     2      |
+----------+-------+------------+
| 1-4-2018 |   A   |     1      |
+----------+-------+------------+
| 1-4-2018 |   B   |     1      |
+----------+-------+------------+

То, что я сделал до сих пор, но, похоже, не работает:

SELECT a.Place
,c.Date
,(SELECT COUNT(DISTINCT(b.BSN))
FROM Person as b
WHERE b.Startdate < c.Date
AND (b.Enddate > c.Date OR b.Enddate is null)
AND (b.Date of death > c.Date OR b.Date of death is null)
AND a.Place = b.Place) as Population
FROM Person as a
JOIN Calender as c
ON a.Startdate <= c.Date
AND a.Enddate >= c.Date
GROUP BY Place, Date

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

1 Ответ

0 голосов
/ 29 января 2019

Первое перекрестное соединение Calender и места для получения пар дата / место.Затем осталось присоединиться к лицам на месте и дате.Наконец, сгруппируйте по дате и месту, чтобы получить количество людей за этот день и место.

SELECT [ca].[Date],
       [pl].[Place],
       count([pe].[Place]) [Population]
       FROM [Calender] [ca]
            CROSS JOIN (SELECT DISTINCT
                               [pe].[Place]
                               FROM [Persons] [pe]) [pl]
            LEFT JOIN [Persons] [pe]
                      ON [pe].[Place] = [pl].[Place]
                         AND [pe].[Startdate] <= [ca].[Date]
                         AND (colaesce([pe].[Enddate],
                                       [pe].[Date of death]) IS NULL
                               OR coalesce([pe].[Enddate],
                                           [pe].[Date of death]) > [ca].[Date])
       GROUP BY [ca].[Date],
                [pl].[Place]
       ORDER BY [ca].[Date],
                [pl].[Place];

Некоторые примечания и предположения:

  • Если у вас есть таблица с перечнем мест, используйтечто вместо псевдонимов подзапроса [pl].У меня просто не было другого варианта с данными таблицами.
  • Я считаю, что Date of death также подразумевает Enddate для того же дня.Возможно, вы захотите рассмотреть триггер, который автоматически устанавливает Enddate на Date of death, если он не равен нулю.Это сделало бы вещи проще и, вероятно, более последовательными.
...