Сводный столбец по условию - PullRequest
0 голосов
/ 07 мая 2018

Я должен написать отчет о доступности для домашней страницы. В таблице, которая доступна для меня, у меня есть 2 столбца. Первый - это статус домашней страницы (0 находится в автономном режиме, а 1 - в сети), а второй - длительность этого статуса в секундах. Пример таблицы может выглядеть так:

-------------------------
|  Status  |  Duration  |  
-------------------------
|  0       |  50        |
-------------------------
|  1       |  10        |
-------------------------
|  1       |  20        |
-------------------------
|  1       |  50        |
-------------------------
|  0       |  50        |
-------------------------
|  0       |  50        |
-------------------------
|  1       |  20        |
-------------------------

В моем отчете это выглядит не очень хорошо, потому что одни и те же данные должны быть объединены в одну строку, а не отображаться в виде нескольких строк, например:

-------------------------
|  Status  |  Duration  |  
-------------------------
|  0       |  50        |
-------------------------
|  1       |  80        |
-------------------------
|  0       |  100       |
-------------------------
|  1       |  20        |
-------------------------

Есть ли способ достичь этого с PostgreSQL?

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

Как я уже сказал, вам понадобится столбец id/datetime для отслеживания прогресса. Только тогда вы сможете использовать LEAD/LAG функцию или TABIBITOSAN метод для этого сценария.

SQL Fiddle

Настройка схемы PostgreSQL 9.6 :

CREATE TABLE t
    (id INT,Status int, Duration int)
;

INSERT INTO t
    (id,Status, Duration)
VALUES
    (1,0, 50),
    (2,1, 10),
    (3,1, 20),
    (4,1, 50),
    (5,0, 50),
    (6,0, 50),
    (7,1, 20)
;

Запрос 1 :

SELECT STATUS
    ,Sum(duration)
FROM (
    SELECT t.*
        ,row_number() OVER (
            ORDER BY id
            ) - row_number() OVER (
            PARTITION BY STATUS ORDER BY id
            ) AS seq
    FROM t
    ) s
GROUP BY STATUS
    ,seq
ORDER BY max(id)

Результаты

| status | sum |
|--------|-----|
|      0 |  50 |
|      1 |  80 |
|      0 | 100 |
|      1 |  20 |
0 голосов
/ 07 мая 2018

Эта агрегация может быть достигнута с помощью оконных функций и группировки:

select max(status) status, sum(duration) duration from (
          select status, duration, sum(case when status <> par then 1 else 0 end) over (order by id) wf from ( 
            select id, status, duration, lag(status, 1) over () par from test
          ) a order by id
      ) a group by wf order by wf

Вам просто нужно правильно установить порядок в оконной функции.

Данные испытаний:

create table test (status int, duration int, id bigserial primary key);

insert into test (status, duration) values (0, 50);
insert into test (status, duration) values (1, 10);
insert into test (status, duration) values (1, 20);
insert into test (status, duration) values (1, 50);
insert into test (status, duration) values (0, 50);
insert into test (status, duration) values (0, 50);
insert into test (status, duration) values (1, 20);

Вывод, как вы хотели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...