Множественный поиск между двумя таблицами

У меня есть две таблицы - первая (это просто пример, но исходный запрос довольно большой)

item_id_t1 серийный номер_t1 страна_t1 клиент snapshot_date_t1 серийный номер_trunc_t1 156648107 222-99950578 ААА ББСС 01.12.2022 99950578 156648107 222-99950578 ААА ББСС 01.11.2022 99950578 156648107 222-99950578 ААА ББСС 01.01.2023 99950578 108279887 888-515179765 ААА ББСС 01.12.2022 515179765 108279887 888-515179765 ААА ББСС 01.11.2022 515179765 108279887 888-515179765 ААА ББСС 01.11.2023 515179765

и второй

серийный номер_trunc_t2 серийный номер_t2 up_ind_t2 99950578 333-99950578 1 515179765 888-515179765 1

Теперь моим первым шагом будет поиск соответствия на основе serial_num_t1 = serial_num_t2, а второй частью кода должен быть поиск всех несопоставленных записей, но на этот раз на основе serial_num_trunc_t1 = serial_num_trunc_t2.

Сначала я начал с таблиц CTE

WITH t1 AS (SELECT * FROM t1),
t2 AS (SELECT * FROM t2)

SELECT a.*
(SELECT t1.*, t2.*
FROM t1
LEFT JOIN t2
ON serial_num_t1 = serial_num_t2) a

INNER JOIN

(SELECT t1.*, t2.*
FROM t1
LEFT JOIN t2
ON t1.serial_num_trunc_t1 = t2.serial_num_trunc_t1
WHERE q.up_ind_t2 <> 1) b
ON a.serial_num_trunc_t1 = b.serial_num_trunc_t2

и вот я застрял. Как снова сравнить несовпадающие значения из таблицы «a» с таблицей «b» на основе t1.serial_num_trunc_t1 = t2.serial_num_trunc_t2, ГДЕ t2.ip_ind_t2 <> 1 В моей итоговой таблице должно быть шесть записей (например, t1), а «up_ind_t2» должен быть заполнен 1 для всех шести записей в итоговой таблице.

Я был бы признателен за вашу помощь.

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
0
56
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я предполагаю, вы хотите

WITH t1 AS (SELECT * FROM t1),
t2 AS (SELECT * FROM t2)

SELECT t1.*, t2.*
FROM t1
LEFT JOIN t2
ON serial_num_t1 = serial_num_t2

UNION ALL

SELECT t1.*, t2.*
FROM t1
INNER JOIN t2
ON t1.serial_num_trunc_t1 = t2.serial_num_trunc_t1
WHERE q.up_ind_t2 <> 1

как Query, LEft JOIN не имеет особого смысла, во-первых, поэтому я удалил его из второго.

второй запрос подразумевает, что у вас есть только 1 запись для каждого serial_num_trunc_t2, и она не равна 1, если нет, вам нужно добавить ограничение

@нбк Это не похоже на мое решение. Я добавил match_level, чтобы увидеть, откуда происходит совпадение: из LEFT JOIN или из INNER JOIN (часть кода UNION). Итак, когда я запускаю ваш код, я получаю те же результаты, что и до части UNION ALL.

WITH t1 AS (SELECT * FROM ib),
t2 AS (SELECT * FROM qu)

SELECT t1.*, t2.*, 1 as match_level
FROM ib t1
LEFT JOIN qu t2
ON serial_num_t1 = serial_num_t2

UNION ALL

SELECT t1.*, t2.*, 2 as match_level
FROM ib t1
INNER JOIN qu t2
ON t1.serial_num_trunc_t1 = t2.serial_num_trunc_t2
WHERE t2.up_ind_t2 <> 1

это выглядит точно так же, как мой запрос, без новых меток

nbk 15.02.2023 13:02

Но ваш запрос не возвращает мне желаемых результатов. В итоговой таблице должны быть заполнены все поля serial_num_trunc_t2, serial_num_t2 и up_ind_t2 (на основе части UNION), а в данной ситуации это не так.

fym 15.02.2023 15:48

Может быть, есть какое-то лучшее решение для этого? Первый шаг — LEFT JOIN t1 на t1 на основе серийного_номера. И он найдет три записи соответствия для serial_num = 888-51517965. Затем мне нужен дополнительный поиск между таблицами t1 и t2 для всех несовпадающих записей из первого запроса, где up_ind_t2 имеет значение NULL на основе serial_num_trunc_t1 = serial_num_trunc_t2, а затем объединить/объединить эти записи в одну таблицу.

fym 15.02.2023 15:53

Я думаю, что нашел решение, но мне нужно проверить его на всем наборе данных. Я изменил: - UNION ALL ---> UNION - WHERE t2.up_ind_t2 <> 1 ---> WHERE t2.up_ind_t2 IS NULL

fym 15.02.2023 18:45

NULL исходит из LEFT JOIN, без него у вас не было бы,

nbk 15.02.2023 18:49
Ответ принят как подходящий

Наконец, это то, что мне было нужно.

with 
ib as (
select * 
from [dbo].[ib] i
left join [dbo].[qu] q
on i.serial_num_t1=q.serial_num_t2),

qu as (
select * 
from [dbo].[ib] i
right join [dbo].[qu] q
on i.serial_num_trunc_t1=q.serial_num_trunc_t2)

select ff.*
from
(select * 
from 
(select ROW_NUMBER() OVER(PARTITION BY q.item_id_t1,
q.serial_num_t1,q.country_t1, q.customer, q.snapshot_date_t1,
q.up_ind_t2 ORDER BY q.snapshot_date_t1, q.up_ind_t2 DESC) AS it_row, q.* 
from qu q
left join ib b
on q.serial_num_trunc_t2 = b.serial_num_trunc_t1) a 

union

select 99 as it_row, zz.* 
from qu as zz ) ff
where it_row = 1

Другие вопросы по теме