Как создать пустые записи для каждого дня недели на все недели - PullRequest
0 голосов
/ 01 марта 2020

У меня есть таблица, содержащая некоторые данные о событиях. Это выглядит следующим образом:

+------+-----------+--------+
| Week |   day     | value1 |
+------+-----------+--------+
|    2 | Monday    |      5 |
|    2 | Thursday  |      2 |
|    2 | Sunday    |      1 |
|    3 | Monday    |      2 |
|    3 | Tuesday   |      2 |
|    3 | Wednesday |      0 |
|    3 | Thursday  |      9 |
|    9 | Friday    |      3 |
+------+-----------+--------+

Теперь я хотел бы, чтобы для каждой недели в этой таблице были записи для каждого дня недели. Если они не существуют, это должно быть незаполненным. Вот так:

+------+-----------+--------+
| Week |   day     | value1 |
+------+-----------+--------+
|    2 | Monday    | 5      |
|    2 | Tuesday   | Null   |
|    2 | Wednesday | Null   |
|    2 | Thursday  | 2      |
|    2 | Friday    | Null   |
|    2 | Saturday  | Null   |
|    2 | Sunday    | 1      |
+------+-----------+--------+

et c.

То, что я до сих пор пытался, это взять все недели в таблице, скрестить их со списком всех дней недели, а затем присоединиться к нему на этой неделе, но безуспешно.

Причиной всего этого упражнения является то, что я могу получить дельта-таблицу с разницей между неделями в день в значении 1.

Все советы приветствуются!

Ответы [ 3 ]

0 голосов
/ 01 марта 2020

Вы можете попробовать следующее решение, если ваша таблица имеет уникальное ограничение на неделю + день:

-- insert results into your table
insert into table (
  -- select combined weeks and days table
  select "day", "week", null "value1" from (
    -- select weeks from range. For example it 1..52 
    select * from generate_series(1, 52) as "week"
  ) a 
  cross join (
    -- select day from array of days.
    select unnest (array['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunaday']) as "day"
  ) t) 
-- prevent rows duplication
on conflict do nothing ;
0 голосов
/ 01 марта 2020

Предполагая, что у вас есть таблица:

CREATE TABLE event_data (
    date date,
    value int
);

, вы можете сделать

SELECT
    *
FROM
    generate_series('2020-jan-1'::date, '2020-jan-15'::date, '1 day') AS date
    LEFT OUTER JOIN event_data USING (date);

, а затем извлечь номер недели и день недели и выполнить форматирование.

0 голосов
/ 01 марта 2020

Если у вас есть значения для каждого дня в таблице, то:

select w.week, d.day, t.value1
from (select distinct week from t) w cross join
     (select distinct day from t) d left join
     t
     on t.week = w.week and t.day = d.day
order by t.week, array_position(array['Monday', 'Tuesday', . . . ], d.day);

Если в таблице нет всех семи дней, вы можете сгенерировать их:

select w.week, d.day, t.value1
from (select distinct week from t) w cross join
     (values (1, 'Monday'), (2, 'Tuesday'), . .     
     ) d(ord, day) left join
     t
     on t.week = w.week and t.day = d.day
order by w.week, d.ord;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...