У меня есть две таблицы. И я хочу проверить, находится ли значение от одного, между любыми двумя числами в другой таблице. Например таблицы:
table_a:
+--------+-------+---------------------+
| name | count | time |
+--------+-------+---------------------+
| table1 | 10 | 2019-05-03 10:30:00 |
| table1 | 20 | 2019-05-03 11:30:00 |
| table1 | 30 | 2019-05-03 12:30:00 |
| table1 | 40 | 2019-05-03 13:30:00 |
| table1 | 50 | 2019-05-03 14:30:00 |
+--------+-------+---------------------+
table_b:
+--------+-------+
| name | count |
+--------+-------+
| table1 | 35 |
+--------+-------+
Из этого я хочу получить самое близкое значение выше и ниже числа в table_b, которое существует в table_a, а затем показать это как «соответствие», а затем также отобразить времена ближайшего значения выше и ниже этого числа. Таким образом, результаты должны выглядеть примерно так:
Result:
+--------+--------------+---------------------+---------------------+
| name | count | time_before | time_after |
+--------+--------------+---------------------+---------------------+
| table1 | Counts Match | 2019-05-03 12:30:00 | 2019-05-03 13:30:00 |
+--------+--------------+---------------------+---------------------+
Если это не совпадает, то в результатах будет показано, что оно не совпадает, а время будет пустым.
Спасибо
3 ответа
Вы можете сделать это, сгенерировав таблицу из before
и after
значений для count
и time
в table_a
, а затем JOIN
ее в table_b
так, что table_b.count
находится между count_before
и count_after
:
SELECT a.name,
a.count_before || ',' || a.count_after AS count,
a.time_before,
a.time_after
FROM (SELECT name,
lag(count) over (order by time) AS count_before,
count AS count_after,
lag(time) over (order by time) AS time_before,
time AS time_after
FROM table_a) a
JOIN table_b b ON b.count BETWEEN a.count_before AND a.count_after
Выход:
name count time_before time_after
table1 30,40 2019-05-03T12:30:00.000Z 2019-05-03T13:30:00.000Z
Вы можете сгенерировать список начальных / конечных отсчетов (и временных меток) с помощью оконной функции, а затем соединить это со второй таблицей:
with ranges as (
select name,
"time" as time_start,
"count" as count_start,
lead("count") over w as count_end,
lead("time") over w as time_end
from table_a
window w as (partition by name order by "time")
)
select t2.name, t2."count", r.count_start, r.count_end, r.time_start, r.time_end
from table_b t2
join ranges r on r.name = t2.name and t2."count" between r.count_start and r.count_end;
Пример в Интернете: https://rextester.com/MBYZYU33789
Одним из методов является боковое соединение:
select b.*, a.lower, a.upper
from table_b b cross join lateral
(select max(lower) as lower, max(upper) as upper
from ((select a.time as lower, null as upper
from table_a a
where a.value <= b.value
order by b.time desc
fetch first 1 row only
) union all
(select null as lower, a.time as upper
from table_a a
where a.value >= b.value
order by b.time asc
fetch first 1 row only
)
) a
) a
Похожие вопросы
Новые вопросы
sql
Язык структурированных запросов (SQL) - это язык запросов к базам данных. Вопросы должны включать примеры кода, структуру таблицы, примеры данных и тег для используемой реализации СУБД (например, MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2 и т. Д.). Если ваш вопрос относится исключительно к конкретной СУБД (использует определенные расширения / функции), используйте вместо этого тег этой СУБД. Ответы на вопросы, помеченные SQL, должны использовать стандарт ISO / IEC SQL.