#sql #netezza
Вопрос:
У меня есть следующий пример таблицы, которая была сгруппирована по исходному набору данных.
Я хочу найти дату, в которой значение «plus_one» является ближайшим совпадением (первый результат выше) со столбцом «значение» в данном «отделе». Это должно быть произведено в столбце «return_dt».
Например, в первой строке 1.2 в столбце «plus_one» для отдела «Одежда» ближе всего к 1.36667 в столбце «значение», поэтому в первой строке необходимо вернуть соответствующую дату (6/19/20) в столбце «return_dt» для того же отдела.
Я знаком с оконными функциями и использую ORDER BY abs (), чтобы найти ближайшее совпадение. У меня возникли проблемы с их объединением, чтобы найти индексированную дату в одной таблице.
end_dt | отдел | ценность | плюс один | return_dt |
---|---|---|---|---|
6/30/2020 0:00 | Одежда | 0.2 | 1.2 | 6/19/2020 |
6/29/2020 0:00 | Одежда | 0.393333 | 1.393333 | 6/18/2020 |
6/28/2020 0:00 | Одежда | 0.393333 | 1.393333 | 6/18/2020 |
6/27/2020 0:00 | Одежда | 0.393333 | 1.393333 | 6/17/2020 |
6/26/2020 0:00 | Одежда | 0.573333 | 1.573333 | 6/17/2020 |
6/25/2020 0:00 | Одежда | 0.726667 | 1.726667 | 6/16/2020 |
6/24/2020 0:00 | Одежда | 0.853333 | 1.853333 | 6/15/2020 |
6/23/2020 0:00 | Одежда | 1.02 | 2.02 | 6/12/2020 |
6/22/2020 0:00 | Одежда | 1.166667 | 2.166667 | 6/12/2020 |
6/21/2020 0:00 | Одежда | 1.166667 | 2.166667 | |
6/20/2020 0:00 | Одежда | 1.166667 | 2.166667 | |
6/19/2020 0:00 | Одежда | 1.366667 | 2.366667 | |
6/18/2020 0:00 | Одежда | 1.5 | 2.5 | |
6/17/2020 0:00 | Одежда | 1.713333 | 2.713333 | |
6/16/2020 0:00 | Одежда | 1.84 | 2.84 | |
6/15/2020 0:00 | Одежда | 1.986667 | 2.986667 | |
6/14/2020 0:00 | Одежда | 1.986667 | 2.986667 | |
6/13/2020 0:00 | Одежда | 1.986667 | 2.986667 | |
6/12/2020 0:00 | Одежда | 2.24 | 3.24 | |
… | … | … | … | … |
6/30/2020 0:00 | Игрушки | 0.2 | 1.2 | 6/19/2020 |
6/29/2020 0:00 | Игрушки | 0.393333 | 1.393333 | 6/18/2020 |
6/28/2020 0:00 | Игрушки | 0.393333 | 1.393333 | 6/18/2020 |
6/27/2020 0:00 | Игрушки | 0.393333 | 1.393333 | 6/17/2020 |
6/26/2020 0:00 | Игрушки | 0.573333 | 1.573333 | 6/17/2020 |
6/25/2020 0:00 | Игрушки | 0.726667 | 1.726667 | 6/16/2020 |
6/24/2020 0:00 | Игрушки | 0.853333 | 1.853333 | 6/15/2020 |
6/23/2020 0:00 | Игрушки | 1.02 | 2.02 | 6/12/2020 |
6/22/2020 0:00 | Toys | 1.166667 | 2.166667 | 6/12/2020 |
6/21/2020 0:00 | Toys | 1.166667 | 2.166667 | |
6/20/2020 0:00 | Toys | 1.166667 | 2.166667 | |
6/19/2020 0:00 | Toys | 1.366667 | 2.366667 | |
6/18/2020 0:00 | Toys | 1.5 | 2.5 | |
6/17/2020 0:00 | Toys | 1.713333 | 2.713333 | |
6/16/2020 0:00 | Toys | 1.84 | 2.84 | |
6/15/2020 0:00 | Toys | 1.986667 | 2.986667 | |
6/14/2020 0:00 | Toys | 1.986667 | 2.986667 | |
6/13/2020 0:00 | Toys | 1.986667 | 2.986667 | |
6/12/2020 0:00 | Toys | 2.24 | 3.24 | |
… | … | … | … | … |
6/30/2020 0:00 | Games | 0.2 | 1.2 | 6/19/2020 |
6/29/2020 0:00 | Игры | 0.393333 | 1.393333 | 6/18/2020 |
6/28/2020 0:00 | Игры | 0.393333 | 1.393333 | 6/18/2020 |
6/27/2020 0:00 | Игры | 0.393333 | 1.393333 | 6/17/2020 |
6/26/2020 0:00 | Игры | 0.573333 | 1.573333 | 6/17/2020 |
6/25/2020 0:00 | Игры | 0.726667 | 1.726667 | 6/16/2020 |
6/24/2020 0:00 | Игры | 0.853333 | 1.853333 | 6/15/2020 |
6/23/2020 0:00 | Игры | 1.02 | 2.02 | 6/12/2020 |
6/22/2020 0:00 | Игры | 1.166667 | 2.166667 | 6/12/2020 |
6/21/2020 0:00 | Игры | 1.166667 | 2.166667 | |
6/20/2020 0:00 | Игры | 1.166667 | 2.166667 | |
6/19/2020 0:00 | Игры | 1.366667 | 2.366667 | |
6/18/2020 0:00 | Игры | 1.5 | 2.5 | |
6/17/2020 0:00 | Игры | 1.713333 | 2.713333 | |
6/16/2020 0:00 | Игры | 1.84 | 2.84 | |
6/15/2020 0:00 | Игры | 1.986667 | 2.986667 | |
6/14/2020 0:00 | Игры | 1.986667 | 2.986667 | |
6/13/2020 0:00 | Игры | 1.986667 | 2.986667 | |
6/12/2020 0:00 | Игры | 2.24 | 3.24 | |
… | … | … | … | … |
Я попробовал коррелированный запрос, такой как
select t.*,
(select t2.end_dt
from t t2
where t2.value > t.plus_one
order by t2.value
limit 1
) as return_dt
from t;
но Netezza говорит: «ОШИБКА [HY000] ОШИБКА: (2) Эта форма коррелированного запроса не поддерживается — подумайте о переписывании».
Есть идеи, как я могу создать столбец для return_dt?
Комментарии:
1. Не забывайте, что вы можете присоединить таблицу к себе
2. @Cosmos . . . Netezza не является Postgres, поэтому я удалил тег Postgres.
3. @GordonLinoff Спасибо, я все еще учусь 🙂
Ответ №1:
Боковое соединение или коррелированный подзапрос кажутся таким простым подходом:
select t.*,
(select t2.end_dt
from t t2
where t2.dept = t.dept and
t2.value > t.plus_one
order by t2.value
limit 1
) as return_dt
from t;
Это довольно болезненно (и неэффективно) писать без соответствующего подзапроса. Но …
select t.*
from (select t.end_dt, t.dept, t.value, t.plus_one,
tnext.end_dt as return_dt,
row_number() over (partition by t.end_dt, t.dept, t.value, t.plus_one order by tnext.value asc) as seqnum
from t left join
t tnext
on tnext.dept = t.dept and
tnext.value > t.plus_one
) t
where seqnum = 1;
Комментарии:
1. Спасибо, это похоже на то, где мне нужно быть. Однако, похоже, это решение не работает с моим полным набором данных, который на самом деле сгруппирован по отдельному полю. Я получаю следующую ошибку от Netezza «ОШИБКА [HY000] Эта форма коррелированного запроса не поддерживается — подумайте о переписывании» Я внес изменения в вышеуказанный вопрос, чтобы включить более полное представление о ситуации, есть ли шанс, что вы могли бы помочь мне изменить?
2. @Cosmos . . . Помогает ли это, если есть условие равенства на
dept
?3. Невероятно, это работает безупречно. Большое вам спасибо!!!