Стандартный SQL: LEFT JOIN по двум условиям, используя BETWEEN - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть следующий запрос в 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)

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

Ответы [ 5 ]

0 голосов
/ 07 сентября 2018

ЛЕВОЕ СОЕДИНЕНИЕ всегда эквивалентно СОЮЗУ:

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

Эта последняя часть может быть записана как

SELECT T1. *, Ноль как T2_C1, ноль как T2_C2, ... ОТ Т1 ГДЕ НЕ СУЩЕСТВУЕТ (ВЫБЕРИТЕ * ОТ ГДЕ Т2)

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

0 голосов
/ 07 сентября 2018

Вместо записи (*), вы должны написать Table_1. * и т. д.

SELECT

Table_1. * , Таблица 2. *

FROM

Таблица_1 ЛЕВОЕ СОЕДИНЕНИЕ Таблица_2

ON

(отметка времени между TimeStampStart и TimeStampEnd)

0 голосов
/ 07 сентября 2018

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

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

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

0 голосов
/ 07 сентября 2018

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

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 на равенство).

0 голосов
/ 07 сентября 2018

Интересно. Это работает для меня в стандартном 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
...