Левое соединение по ROW_NUMBER() ПОВЕРХ (РАЗДЕЛА

#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 дало правильные результаты!