Агрегировать столбец по условию

Мне нужно написать отчет о работоспособности домашней страницы. В доступной мне таблице у меня 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?

попробуйте использовать group by

gvmani 07.05.2018 15:24

Используйте group by duration

mahan 07.05.2018 15:25

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

Kaushik Nayak 07.05.2018 16:45

Проверьте мой ответ и дайте мне знать, что это помогло. Также прочтите: stackoverflow.com/help/someone-answers

Kaushik Nayak 20.05.2018 19:51
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
38
2

Ответы 2

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

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);

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

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

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 |

Плюс к методу Табибитозана, это очень интересно.

JustMe 08.05.2018 09:10

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