Отображать разделенные запятыми значения для несуществующих строк в postgres - PullRequest
0 голосов
/ 02 июня 2018

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

t               mean        max     min     std     data_id
4/14/2010 0:00  12.6941 12.6941 12.6941 12.6941          1
4/14/2010 0:00  12.3851 12.3851 12.3851 12.3851          2
4/14/2010 0:20  12.389  12.389  12.389  12.389           1
4/14/2010 0:20  12.1836 12.1836 12.1836 12.1836          2
4/14/2010 0:20  11.3887 11.3887 11.3887 11.3887          4

Я хочу преобразовать данные в

t,str_agg
'2010-04-14 00:00:00','12.6941','12.6941','12.6941','12.6941','12.3851','12.3851','12.3851','12.3851',,,,
'2010-04-14 00:10:00','12.3890','12.3890','12.3890','12.3890','12.1836','12.1836','12.1836','12.1836','11.3887','11.3887','11.3887','11.3887

Я пробовал следующий запрос: -

WITH dataset AS (
    SELECT *
    FROM
        (
            VALUES
            ('2010-04-14T00:00'::TIMESTAMP, 12.6941, 12.6941, 12.6941, 12.6941, 1),
            ('2010-04-14T00:00'::TIMESTAMP, 12.3851, 12.3851, 12.3851, 12.3851, 2),
            ('2010-04-14T00:20'::TIMESTAMP, 12.389, 12.389, 12.389, 12.389, 1),
            ('2010-04-14T00:20'::TIMESTAMP, 12.1836, 12.1836, 12.1836, 12.1836, 2),
            ('2010-04-14T00:20'::TIMESTAMP, 11.3887, 11.3887, 11.3887, 11.3887, 13)
        ) AS data(t, mean, max, min, std, data_id)
),
dataset_full AS (
    SELECT
        coalesce(t, time) AS t,
        mean,
        max,
        min,
        std,
        data_id
    FROM
        generate_series(
                (SELECT min(t) FROM dataset),
                (SELECT max(t) FROM dataset),
                '10 minutes')
            AS times(time)
        CROSS JOIN generate_series(
                       (SELECT min(data_id) FROM dataset),
                       (SELECT max(data_id) FROM dataset))
            AS data_id(id)
        LEFT JOIN dataset ON times.time = dataset.t AND data_id.id = dataset.data_id
)
SELECT
    t,
    string_agg(concat(mean, ',', max, ',', min, ',', std), ',')
FROM dataset_full
GROUP BY t
ORDER BY t;

И я получаю следующий результат: -

'2010-04-14 00:00:00','12.6941,12.6941,12.6941,12.6941,12.3851,12.3851,12.3851,12.3851,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'
'2010-04-14 00:10:00',',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'
'2010-04-14 00:20:00','12.389,12.389,12.389,12.389,12.1836,12.1836,12.1836,12.1836,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,11.3887,11.3887,11.3887,11.3887'

Но я хочу следующий результат: -

'2010-04-14 00:00:00','12.6941,12.6941,12.6941,12.6941,12.3851,12.3851,12.3851,12.3851,,,,'
'2010-04-14 00:20:00','12.389,12.389,12.389,12.389,12.1836,12.1836,12.1836,12.1836,11.3887,11.3887,11.3887,11.3887'

Может кто-нибудь, пожалуйста, помогите мне в решении вышеуказанной проблемы!

Ответы [ 2 ]

0 голосов
/ 02 июня 2018

Ваша основная проблема заключается в том, что вы генерируете временные интервалы и идентификаторы набора данных, а не считываете их из данных.Это влияет на dataset_full CTE.Похоже, вам нужны только значения, которые находятся где-то в данных.

Следовательно:

with dataset as (
      select *
      from (values ('2010-04-14T00:00'::TIMESTAMP, 12.6941, 12.6941, 12.6941, 12.6941, 1),
                   ('2010-04-14T00:00'::TIMESTAMP, 12.3851, 12.3851, 12.3851, 12.3851, 2),
                   ('2010-04-14T00:20'::TIMESTAMP, 12.389, 12.389, 12.389, 12.389, 1),
                   ('2010-04-14T00:20'::TIMESTAMP, 12.1836, 12.1836, 12.1836, 12.1836, 2),
                   ('2010-04-14T00:20'::TIMESTAMP, 11.3887, 11.3887, 11.3887, 11.3887, 13)
           ) AS data(t, mean, max, min, std, data_id)
      ),
     dataset_full as (
       select t.t, d.data_id,
              ds.mean, ds.max, ds.min, ds.std
       from (select distinct t from dataset) t cross join
            (select distinct data_id from dataset) d left join
            dataset ds
            on ds.t = t.t and ds.data_id = d.data_id
     )
select t,string_agg(concat(mean, ',', max, ',', min, ',', std), ',' order by data_id)
from dataset_full
group by t
order by t;

Здесь - это скрипта SQL.

Такжеобратите внимание на order by в string_agg().Предположительно, вам нужны эти значения в порядке dataset_id.

0 голосов
/ 02 июня 2018

Вы можете заменить LEFT JOIN на JOIN:

WITH dataset AS (
    SELECT *
    FROM(VALUES
     ('2010-04-14T00:00'::TIMESTAMP, 12.6941, 12.6941, 12.6941, 12.6941, 1),
     ('2010-04-14T00:00'::TIMESTAMP, 12.3851, 12.3851, 12.3851, 12.3851, 2),
     ('2010-04-14T00:20'::TIMESTAMP, 12.389, 12.389, 12.389, 12.389, 1),
     ('2010-04-14T00:20'::TIMESTAMP, 12.1836, 12.1836, 12.1836, 12.1836, 2),
     ('2010-04-14T00:20'::TIMESTAMP, 11.3887, 11.3887, 11.3887, 11.3887, 13)
     ) AS data(t, mean, max, min, std, data_id)
),
dataset_full AS (
    SELECT coalesce(t, time) AS t,
        mean,
        max,
        min,
        std,
        data_id
    FROM generate_series(
                (SELECT min(t) FROM dataset),
                (SELECT max(t) FROM dataset),
                '10 minutes')
            AS times(time)
        CROSS JOIN generate_series(
                       (SELECT min(data_id) FROM dataset),
                       (SELECT max(data_id) FROM dataset))
            AS data_id(id)
        JOIN dataset    -- here
          ON times.time = dataset.t 
         AND data_id.id = dataset.data_id
)
SELECT t,string_agg(concat(mean, ',', max, ',', min, ',', std), ',')
FROM dataset_full
GROUP BY t
ORDER BY t;

DBFiddle Demo

РЕДАКТИРОВАТЬ:

Удаляется ,,,, в первой строке, чего я не хочу

...
 cte2 AS (
  SELECT    t,   string_agg(concat(mean, ',', max, ',', min, ',', std), ',') AS s
       , COUNT(*) AS c
  FROM dataset_full
  GROUP BY t
)
SELECT t, s|| REPEAT(',,,,', (MAX(c) OVER() - c)::int)
FROM cte2
ORDER BY t; 

DBFiddle Demo2

Выход:

┌─────────────────────┬─────────────────────────────────────────────────────────────────────────────────────────────┐
│ t                   │ result                                                                                      │
├─────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
│ 2010-04-14 00:00:00 │ 12.6941,12.6941,12.6941,12.6941,12.3851,12.3851,12.3851,12.3851,,,,                         │
│ 2010-04-14 00:20:00 │ 12.389,12.389,12.389,12.389,12.1836,12.1836,12.1836,12.1836,11.3887,11.3887,11.3887,11.3887 │
└─────────────────────┴─────────────────────────────────────────────────────────────────────────────────────────────┘
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...