#sql #google-bigquery #left-join #minimum
#sql #google-bigquery #левое соединение #минимальный
Вопрос:
Я использую StandardSQL в BigQuery и имею 7 таблиц по 10-75 столбцов в каждой и тысячи строк. Для простоты я буду использовать только соответствующие таблицы и столбцы для того, что я пытаюсь выполнить.
Таблица 1
Элемент | Desc |
---|---|
12341 | abcd |
23451 | bcda |
34561 | cdab |
45671 | dabc |
Таблица 2
Подпункт | Расположение | ON_OFF | Из первых рук | OnOrder |
---|---|---|---|---|
12345 | 1 | НА | 3 | 5 |
12345 | 2 | НА | 4 | 2 |
12345 | 3 | НА | 2 | 4 |
12346 | 1 | НА | 7 | 7 |
12346 | 2 | НА | 1 | 4 |
12346 | 3 | НА | 8 | 7 |
23451 | 1 | ВЫКЛ | 1 | 1 |
23451 | 2 | ВЫКЛ | 3 | 2 |
34567 | 1 | НА | 6 | 0 |
34567 | 2 | НА | 1 | 5 |
34568 | 1 | НА | 2 | 0 |
34568 | 2 | НА | 3 | 10 |
45671 | 2 | НА | 5 | 1 |
Таблица 3
Элемент | Подпункт |
---|---|
12341 | 12346 |
23451 | 23451 |
34561 | 34567 |
34561 | 34568 |
Текущий результат
Элемент | Desc | ON_OFF | О | OO |
---|---|---|---|---|
12341 | abcd | НА | 9 | 11 |
12341 | abcd | НА | 16 | 18 |
23451 | bcda | ВЫКЛ | 4 | 3 |
34561 | cdab | НА | 7 | 5 |
34561 | cdab | НА | 5 | 10 |
45671 | dabc | НА | 5 | 1 |
Желаемый результат
Элемент | Desc | ON_OFF | О | OO |
---|---|---|---|---|
12341 | abcd | НА | 9 | 18 |
23451 | bcda | ВЫКЛ | 4 | 3 |
34561 | cdab | НА | 5 | 5 |
45671 | dabc | НА | 5 | 1 |
Я ищу минимальное значение OH и минимальное значение OO для каждого элемента, и, как и в случае с элементом 45671, это не соответствует одному и тому же номеру подпункта.
Текущий код, предоставляющий мне текущую таблицу результатов, является:
Select
Table1.Item,
Table1.Desc,
Table2.ON_OFF,
Table2.OH,
Table2.OO
From Table1
Left Join Table3
On Table1.Item = Table3.Item
Left Join
(Select SubItem, ON_OFF, Sum(OnHand) As OH, Sum(OnOrder) As OO
From Table 2
Group by 1,2)
ON Table3.SubItem = Table2.SubItem;
Ищу идеи, поскольку я все еще новичок в SQL, и текущий фактический код связывает 7 таблиц с различными объединениями, чтобы построить итоговую таблицу с 45 столбцами и тысячами строк. Я рассмотрел использование RowNumber() и Partition By , но я не уверен, куда это приведет. Также думал, что разделение OO и OH на два объединения может помочь.
Любые предложения приветствуются! Спасибо!
Комментарии:
1. Ваша постановка задачи и результаты не совпадают. «18» не является минимальным значением OO для первого элемента.
Ответ №1:
Глядя на ваши примеры данных, кажется, что вы можете использовать group by
и агрегировать функцию min
следующим образом:
Select Table1.Item,
Table1.Desc,
Table2.ON_OFF,
Min(Table2.OH),
Min(Table2.OO)
From Table1
Left Join Table3
On Table1.Item = Table3.Item
Left Join (Select SubItem,
ON_OFF,
Sum(OnHand) As OH,
Sum(OnOrder) As OO
From Table2
Group by 1,2) Table2
ON Table3.SubItem = Table2.SubItem
Group by Table1.Item, Table1.Desc, Table2.ON_OFF;
Ответ №2:
Я работал с ним после того, как получил столь необходимый сон…
Я придумал следующее, и оно работает!
SELECT T1.Item,
T1.Desc,
T3_1.ONOFF,
T3_1.OH,
T3_2.OO
FROM Table1 T1
Left Join
(Select Item, SubItem,T2_1.O_O as ONOFF, T2_1.OH1 as OH,
ROW_NUMBER() OVER(PARTITION BY Item ORDER BY T2_1.OH1) as rn
FROM T2_1
Left Join
(Select SubItem, SUM(IFNULL(OnHand,0)) AS OH1,
FROM Table2
GROUP BY 1) T2_1
ON T2_1.SubItem = T3_1.SubItem) T3_1
On T1.Item = T3_1.Item
Left Join
(Select Item, SubItem, T2_2.OO1 as OO,
ROW_NUMBER() OVER(PARTITION BY Item ORDER BY T2_2.OO1) as rn2
FROM T2_2
Left Join
(Select SubItem, SUM(IFNULL(OnOrder,0)) AS OO1,
FROM Table2
GROUP BY 1) T2_2
ON T2_2.SubItem = T3_2.SubItem) T3_2
On T1.Item = T3_2.Item
Where rn = 1 and rn2 = 1;
Спасибо!
Комментарии:
1. если вы действительно думаете, что ваш ответ действительно работает — пожалуйста, дважды проверьте его — у вас могут быть некоторые опечатки — пожалуйста, исправьте это!