Как сделать многораздельное внешнее объединение в BigQuery - PullRequest
2 голосов
/ 10 октября 2019

Я бы хотел реализовать секционированное внешнее объединение в BigQuery. Чтобы привести конкретный пример, я бы хотел получить разделенное внешнее объединение в качестве принятого ответа: https://dba.stackexchange.com/questions/227069/what-is-a-partitioned-outer-join

Я понимаю, что существует много дискуссий на эту тему, но я не могу этого сделатьработать под BigQuery. Я добавил partition by date после левой таблицы, следуя тому же синтаксису в ответе, как показано ниже:

select * from ( 
 select '2019-01-17' as date, 'London' as location, 11 as qty   
 union all   
 select '2019-01-15' as date, 'London' as location, 10 as qty   
 union all   
 select '2019-01-16' as date, 'Paris' as location, 20 as qty   
 union all   
 select '2019-01-17' as date, 'Boston' as location, 31 as qty   
 union all   
 select '2019-01-16' as date, 'Boston' as location, 30 as qty 
) as sales partition by (date)  
right join 
(   
 select 'London' as location   
 union all   
 select 'Paris' as location   
 union all   
 select 'Boston' as location   
) 
as loc 
using (location)

Целевой результат, который я ищу:

date      qty    location  
15-JAN-19  NULL  Boston  
15-JAN-19  10    London  
15-JAN-19  NULL  Paris   
16-JAN-19  30    Boston  
16-JAN-19  NULL  London  
16-JAN-19  20    Paris   
17-JAN-19  31    Boston  
17-JAN-19  11    London  
17-JAN-19  NULL  Paris 

Но я получилследующая ошибка: Синтаксическая ошибка: неожиданное ключевое слово PARTITION в [11:12]

Как я могу реализовать его в BigQuery?

1 Ответ

2 голосов
/ 11 октября 2019

Ниже для BigQuery Standard SQL

#standardSQL
SELECT `date`, qty, location 
FROM (SELECT DISTINCT `date` FROM sales)
CROSS JOIN loc 
LEFT JOIN sales
USING (`date`, location)

Вы можете протестировать, поиграть с выше, используя примеры данных из вашего вопроса, как в примере ниже

#standardSQL
WITH sales AS (
 SELECT '2019-01-17' AS `date`, 'London' AS location, 11 AS qty UNION ALL   
 SELECT '2019-01-15', 'London', 10 UNION ALL   
 SELECT '2019-01-16', 'Paris', 20 UNION ALL   
 SELECT '2019-01-17', 'Boston', 31 UNION ALL   
 SELECT '2019-01-16', 'Boston', 30 
), loc AS (   
 SELECT 'London' AS location UNION ALL   
 SELECT 'Paris' UNION ALL   
 SELECT 'Boston' 
) 
SELECT `date`, qty, location 
FROM (SELECT DISTINCT `date` FROM sales)
CROSS JOIN loc 
LEFT JOIN sales
USING (`date`, location)
-- ORDER BY `date`, location    

с результатом ниже

Row date        qty     location     
1   2019-01-15  null    Boston   
2   2019-01-15  10      London   
3   2019-01-15  null    Paris    
4   2019-01-16  30      Boston   
5   2019-01-16  null    London   
6   2019-01-16  20      Paris    
7   2019-01-17  31      Boston   
8   2019-01-17  11      London   
9   2019-01-17  null    Paris    

В случае, если вам нужны даты в формате 15-ЯНВ-19 - вы ниже

#standardSQL
SELECT FORMAT_DATE('%d-%b-%y', CAST(`date` AS DATE)) AS `date`, qty, location 
FROM (SELECT DISTINCT `date` FROM sales)
CROSS JOIN loc 
LEFT JOIN sales
USING (`date`, location)

, поэтому результат будет

Row date        qty     location     
1   15-Jan-19   null    Boston   
2   15-Jan-19   10      London   
3   15-Jan-19   null    Paris    
4   16-Jan-19   30      Boston   
5   16-Jan-19   null    London   
6   16-Jan-19   20      Paris    
7   17-Jan-19   31      Boston   
8   17-Jan-19   11      London   
9   17-Jan-19   null    Paris    
...