#sql #google-bigquery #left-join #partitioning
#sql #google-bigquery #левое соединение #разделение
Вопрос:
У меня есть две таблицы: одна с информацией о продажах, а другая с информацией о доставке. Оба находятся на уровне элемента для каждого заказа. Другими словами, каждая запись в обеих таблицах будет иметь только количество, равное 1, даже если количество элементов в заказе кратно.
Таблица 1
order_number | product_code | стоимость | Валюта |
---|---|---|---|
100 | aa | $10 | Долл. США |
100 | aa | $10 | Долл. США |
101 | bb | $15 | Долл. США |
Таблица 2
order_number | product_code | carrier_service | shipment_cost |
---|---|---|---|
100 | aa | Носитель A | $7 |
100 | aa | Носитель B | $7 |
101 | bb | Носитель C | $13 |
Мне нужно объединить таблицы, чтобы извлечь аспекты из каждой. Проблема в том, что для каждой записи нет уникального идентификатора. Сначала я попытался объединить две таблицы в order_number и product_code, однако это привело к дублированию результатов (из-за отсутствия уникальности).
Затем я попытался добавить ROW_NUMBER() ПОВЕРХ (РАЗДЕЛА … чтобы присвоить номер строки и попытался добавить это условие в соединение, но у меня все еще не получается. Значения из второго CTE не доходят до конечных результатов, но если вы должны были запустить его отдельно, значения заполняются.
WITH ss AS (
SELECT
ROW_NUMBER() OVER (PARTITION BY product_code) AS row_id,
order_number,
product_code,
cost,
currency,
FROM sales
ORDER BY order_number, product_code, ROW_NUMBER() OVER (PARTITION BY product_code)),
sis AS (
SELECT
ROW_NUMBER() OVER (PARTITION BY product_code) AS row_id,
order_number,
product_code,
carrier_service,
shipment_cost
FROM items
GROUP BY 1,2,3,4,5,6
ORDER BY order_number, product_code, ROW_NUMBER() OVER (PARTITION BY product_code))
Select
ss.order_number,
ss.product_code,
ss.cost
ss.currency,
sis.carrier_service,
sis.shipment_cost,
FROM ss
LEFT JOIN sis
ON ss.order_number=sis.order_number AND ss.product_code=sis.product_code and ss.row_id=sis.row_id
ORDER BY ss.order_number, ss.product_code
Желаемый результат
order_number | product_code | стоимость | Валюта | carrier_service | shipment_cost |
---|---|---|---|---|---|
100 | aa | $10 | Долл. США | Носитель A | $7 |
100 | aa | $10 | Долл. США | Носитель B | $7 |
101 | bb | $15 | Долл. США | Носитель C | $13 |
Фактический результат
order_number | product_code | стоимость | Валюта | carrier_service | shipment_cost |
---|---|---|---|---|---|
100 | aa | $10 | Долл. США | Null | Null |
100 | aa | $10 | Долл. США | Null | Null |
101 | bb | $15 | Долл. США | Null | Null |
Я не могу присоединиться к номерам строк? Или есть лучший подход к этой проблеме?
Ответ №1:
рассмотрим ниже
select order_number, product_code, cost, currency, carrier_service, shipment_cost
from (select *, row_number() over(partition by product_code) rn from table1) t1
left join (select *, row_number() over(partition by product_code) rn from table2) t2
using(order_number, product_code, rn)
order by order_number, product_code
если применяется к образцу данных в вашем вопросе — вывод
Пожалуйста, обратите внимание: несмотря на то, что я использовал over(partition by product_code)
как есть в вашем коде — я чувствую, что так и должно быть over(partition by order_number)
— но это неясно, исходя из вашего конкретного вопроса — поэтому я оставляю это на ваше усмотрение при решении проблемы left join, которая является предметом вашего вопроса
Комментарии:
1. Сначала это все еще не работало, однако использование вашего предложения о разделении
order_number
и добавленииORDER BY product_code
дало правильные результаты!