Показать варианты внешней колонки с другой колонкой - PullRequest
0 голосов
/ 09 ноября 2018

У меня есть такая таблица:

Table T:

    colA    |    colB     |    colDate
-----------------------------------------------
     A      |     5       |  2018-11-07 00:00:00
     A      |     7       |  2018-11-07 12:00:00
     A      |     7       |  2018-11-08 23:05:00
     A      |     7       |  2018-11-09 06:15:00
     A      |     7       |  2018-11-09 00:00:00
     B      |     25      |  2018-11-07 00:00:00
     B      |     27      |  2018-11-07 12:00:00
     B      |     27      |  2018-11-08 23:05:00
     B      |     27      |  2018-11-09 06:15:00
     B      |     27      |  2018-11-09 00:00:00

Во-первых, мне нужно перечислить все тщетно каждую переменную, имя которой хранится в colA, а значение хранится в colB.

Для этого я использую окна разделов и, в частности, учитывая тот факт, что я использую Postgres, функцию LAG.

select colA, colB, colDate from (
    select colA, colB, colDate,
        lag(colB) over (partition by colA order by colDate) prev_colB
    from T
    order by colA, colDate
) Tsmart
where
Tsmart.colB != Tsmart.prev_colB or Tsmart.prev_colB is null

, что дает в результате

    colA    |    colB     |    colDate
-----------------------------------------------
     A      |     5       |  2018-11-07 00:00:00
     A      |     7       |  2018-11-07 12:00:00
     B      |     25      |  2018-11-07 00:00:00
     B      |     27      |  2018-11-07 12:00:00

Проблема заключается в том, что внешне после создания Tsmart мне нужно отфильтровать эту таблицу на colDate.

Например, я хочу, чтобы только изменения происходили с 2018-11-09 и далее. Я ожидаю стол вроде

    colA    |    colB     |    colDate
-----------------------------------------------
     A      |     7       |  2018-11-09 06:15:00
     A      |     7       |  2018-11-09 00:00:00
     B      |     27      |  2018-11-09 06:15:00
     B      |     27      |  2018-11-09 00:00:00

но, конечно, если я сделаю тот же выбор, что и раньше, только добавив фильтр colDate на внешнюю, я получу пустую таблицу.

select colA, colB, colDate from (
    select colA, colB, colDate,
        lag(colB) over (partition by colA order by colDate) prev_colB
    from T
    order by colA, colDate
) Tsmart
where
(Tsmart.colB != Tsmart.prev_colB or Tsmart.prev_colB is null)
and Tsmart.colDate > '2018-11-09 00:00:00'

Если я не могу переместить фильтр на colDate внутри Tsmart, есть ли способ получить то, что я хочу?

изменить: лучше объяснил вопрос

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

Я наконец нашел решение. Это действительно очень просто, и состоит в добавлении предыдущей временной метки в строку, а затем в принятии строки, если предыдущее значение отличается от текущего, если предыдущее значение равно нулю или если предыдущая временная метка не соответствует фильтру даты.

На практике:

select colA, colB, colDate from (
    select colA, colB, colDate
        lag(colB) over (partition by colA order by colDate) prev_colB,
        lag(colDate) over (partition by colA order by colDate) prev_colDate,
    from T
    order by colA, colDate
) Tsmart
where
    (Tsmart.colB != Tsmart.prev_colB or Tsmart.prev_colB is null
        or Tsmart.prev_colDate < '2018-11-09 00:00:00')
and Tsmart.colDate > '2018-11-09 00:00:00'
0 голосов
/ 09 ноября 2018

Это отвечает оригинальной версии вопроса.

Разве простая агрегация не делает то, что вы хотите?

select colA, colB, min(coldate)
from t
group by colA, colB;

Затем вы можете добавить условие даты в виде условия where или having - в зависимости от того, что именно вы намереваетесь (хотите, чтобы «первые даты» были после даты; или вы хотите, чтобы первая дата происходит после даты, даже если она была ранее).

Я должен добавить, что если вам действительно нужно больше столбцов, вы можете использовать distinct on:

select distinct on (colA, colB) t.*
from t
group by colA, colB, coldate;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...