Как получить уникальные поля при построении таблицы с использованием Common Table Expression (CTE) в PostgreSQL?

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

Вот моя попытка до сих пор:

WITH
candidates AS (SELECT * FROM generate_series(
  date_trunc('hour', CURRENT_TIMESTAMP - INTERVAL '2 hours'),
  date_trunc('hour', CURRENT_TIMESTAMP - INTERVAL '2 hours')+INTERVAL '1 week',
  INTERVAL '1 hour')),
candidows AS (SELECT EXTRACT(DOW FROM generate_series) FROM candidates),
candidatable AS (SELECT b.date_part AS dow, a.generate_series as start_booking FROM candidates a, candidows b)
SELECT * FROM candidatable WHERE dow != 0;

Возвращенное представление включает столбец dow, который ведет себя так, как я ожидаю, но столбец start_booking просто содержит то же значение, что и повторяется:

 dow |     start_booking
-----+------------------------
   2 | 2017-09-19 11:00:00+01
   2 | 2017-09-19 11:00:00+01
   2 | 2017-09-19 11:00:00+01
   2 | 2017-09-19 11:00:00+01
   2 | 2017-09-19 11:00:00+01
   2 | 2017-09-19 11:00:00+01
   2 | 2017-09-19 11:00:00+01
   2 | 2017-09-19 11:00:00+01
   2 | 2017-09-19 11:00:00+01
   2 | 2017-09-19 11:00:00+01
   2 | 2017-09-19 11:00:00+01
   2 | 2017-09-19 11:00:00+01
   2 | 2017-09-19 11:00:00+01
   3 | 2017-09-19 11:00:00+01
   3 | 2017-09-19 11:00:00+01
   3 | 2017-09-19 11:00:00+01

Если я заменю последний оператор SELECT на:

SELECT * FROM candidates;

Тогда данные, которые я пытаюсь просмотреть как start_booking выше, являются последовательными, как я ожидаю:

    generate_series
------------------------
 2017-09-19 11:00:00+01
 2017-09-19 12:00:00+01
 2017-09-19 13:00:00+01
 2017-09-19 14:00:00+01
 2017-09-19 15:00:00+01
 2017-09-19 16:00:00+01

Что я могу сделать, чтобы данные из sources.generate_series отображались как candidatables.start_booking?

1 ответ

Решение

Дикое предположение - вы пытаетесь:

WITH
candidates AS (SELECT generate_series start_booking, EXTRACT(DOW FROM generate_series) dow FROM generate_series(
  date_trunc('hour', CURRENT_TIMESTAMP - INTERVAL '2 hours'),
  date_trunc('hour', CURRENT_TIMESTAMP - INTERVAL '2 hours')+INTERVAL '1 week',
  INTERVAL '1 hour'))
SELECT * FROM candidates WHERE dow != 0;

?..

Другие вопросы по тегам