Стандартный SQL: LEFT JOIN по двум условиям с использованием BETWEEN

У меня в BigQuery такой запрос:

#Standard SQL

SELECT *
FROM `Table_1`     
LEFT JOIN `Table_2` ON (timestamp BETWEEN TimeStampStart AND TimeStampEnd)

Но я получаю следующую ошибку:

Error: LEFT OUTER JOIN cannot be used without a condition that is an equality of fields from both sides of the join.

Если я использую JOIN вместо LEFT JOIN, он работает, но я хочу сохранить все строки из Table_1 (а также те, которые не соответствуют Table_2)

Как этого добиться?

Какая связь между таблицей 1 и таблицей 2? , если нет никакой связи, я бы предпочел использовать предложение Union вместо соединения, которое не имеет отношения к этому контексту

Kaspa Phani Vardhan 07.09.2018 08:54

Таблица 1 содержит столбец с отметками времени (и некоторыми другими переменными), тогда как Таблица 2 содержит также некоторые другие переменные плюс два столбца с отметками времени (один указывает время начала, а другой указывает время окончания). Поэтому я хотел бы объединить эти две таблицы, чтобы, когда метка времени Table_1 находится между начальным и конечным временем, переменные обеих таблиц объединяются / объединяются.

MC09 07.09.2018 09:06

хорошо, вы можете попробовать SELECT * FROM Table_1 LEFT JOIN Table_2 ON (table1.timestamp> = table2.TimeStampStart AND table1.timestamp <= table2.TimeStampEnd)

Kaspa Phani Vardhan 07.09.2018 09:20

Я пробовал, но, к сожалению, все равно получаю ту же ошибку.

MC09 07.09.2018 09:26

Что вы узнали из множества обращений к вашему сообщению об ошибке с тегами и без них? Как спросить Кроме того, левое соединение возвращает объединение строк внутреннего соединения всех несогласованных строк левой таблицы, расширенных нулями. Таким образом, вы можете объединить отдельные части. Конечно, это часто задаваемые вопросы, если не очевидно. PS Уточняйте, пожалуйста, редактированием сообщений, а не комментариями. PS Замена между неравенствами: BigQuery теперь поддерживает соединения с неравенством - обязательно снимите флажок «Использовать устаревшую опцию SQL».

philipxy 07.09.2018 10:37

@philipxy вышеупомянутый запрос выдает ошибку с "обновленным" SQL.

Salman A 07.09.2018 10:49
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
6
2 274
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Интересно. У меня это работает в стандартном SQL:

select *
from (select 1 as x) a left join
     (select 2 as a, 3 as b) b
     on a.x between b.a and b.b

Я подозреваю, что вы используете устаревший SQL. Такой переход на стандартный SQL. (И оставьте скобки после between.)

Проблема в:

#(Standard SQL)#

Это ничего не делает. Использовать:

#StandardSQL

Спасибо. Я не совсем понимаю, что представляют собой 1,2 и 3 в вашем запросе. Я только добавил # (Standard SQL) # в свой пример, чтобы пояснить, что использую StandardSQL, извините, если это не ясно.

MC09 07.09.2018 08:59

@ MC09. . . Этот запрос - просто демонстрация того, что синтаксис принят в стандартном SQL. Ваша проблема в том, что запрос интерпретируется как Legacy SQL.

Gordon Linoff 07.09.2018 22:46

Привет, согласно документации, "(" имеет особое значение, поэтому попробуйте без скобок.

SELECT * FROM Table_1 LEFT JOIN Table_2 ON Table_1.timestamp >= Table_2.TimeStampStart AND Table_1.timestamp <= Table_2.TimeStampEnd

Документация здесь

Все еще то же сообщение об ошибке. Есть ли другой способ достичь той же цели без использования LEFT JOIN?

MC09 07.09.2018 09:43
Ответ принят как подходящий

Это абсолютно глупо ... но тот же запрос будет работать, если вы добавите условие, которое соответствует столбцу из table1 со столбцом из table2:

WITH Table_1 AS (
  SELECT CAST('2018-08-15' AS DATE) AS Timestamp, 'Foo' AS Foo
  UNION ALL
  SELECT CAST('2018-09-15' AS DATE), 'Foo'
), Table_2 AS (
  SELECT CAST('2018-08-14' AS DATE) AS TimeStampStart, CAST('2018-08-16' AS DATE) AS TimeStampEnd, 'Foo' AS Bar
)
SELECT *
FROM Table_1
LEFT JOIN Table_2 ON Table_1.Foo = Table_2.Bar AND Table_1.Timestamp BETWEEN Table_2.TimeStampStart AND Table_2.TimeStampEnd

Посмотрите, есть ли у вас дополнительные критерии соответствия, которые вы можете использовать (например, другой столбец, который связывает table1 и table2 на равенство).

Я понял! Спасибо!

MC09 07.09.2018 10:30

Великолепно, этот ответ сделал мой день лучше!

Thomas 19.07.2019 16:45

LEFT JOIN всегда эквивалентен UNION:

ВНУТРЕННЕЕ СОЕДИНЕНИЕ между теми же двумя аргументами в одном и том же предикате соединения, и набор строк из первого аргумента, для которого не найдено ни одной подходящей строки (и должным образом расширен нулевыми значениями для всех столбцов, сохраненных из второго аргумента)

Эту последнюю часть можно записать как

ВЫБЕРИТЕ T1. *, Null как T2_C1, null как T2_C2, ... ОТ Т1 ГДЕ НЕ СУЩЕСТВУЕТ (ВЫБРАТЬ * ОТ Т2 ГДЕ)

Так что, если вы произнесете UNION, вы сможете туда добраться.

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