#sql #sql-server
#sql #sql-сервер
Вопрос:
Я хочу объединить 2 оператора выбора, чтобы результат был отличным от записи, однако я хочу опустить повторяющиеся результаты во втором операторе выбора (с учетом некоторых столбцов)
select id,name,[type],[parent] from table1 where [type] = 1
union
select * from table2 // but exclude results from this table where
// a record with the same type and parent exists
// in the first select
Я думал об этом (не проверял):
select * from(
select *,rank() over(order by [type],[parent]) [rank] from(
select id,name,[type],[parent] from table1 where [type] = 1
union
select * from table2) t
) a where rank = 1
но это кажется неправильным, есть ли лучший способ исключить дубликат из второго выбора?
Редактировать:
у каждого элемента могут быть дополнения. и дополнения создаются 2 способами:
1. специально созданные дополнения в table1
2. публичное определение того, что элемент типа x должен иметь надстройку
first select получает список дополнений, специально созданных для элементов, table2 создайте список дополнений для всех элементов, теперь будет дублированное дополнение, если было дополнение, специально созданное для элемента.
Комментарии:
1. можете ли вы предоставить некоторые примеры данных
2.
UNION
удаляет дубликаты.UNION ALL
это способ сохранить дубликаты.3. @Jonny как я уже сказал в вопросе, они не являются полными дубликатами, но я считаю, что у них тот же родительский элемент и тип, что и у дубликатов (хотя у них могут быть разные идентификаторы)
Ответ №1:
попробуйте
select * from table1
union
select * from table2
where not exists(select 1 from table1
where table2.parent = table1.parent
and table2.type = table1.type)
Комментарии:
1. было бы лучше, если бы вы могли объяснить, что он делает.
Ответ №2:
попробуйте это:
;WITH cte AS (
SELECT *, 1 AS SetID FROM table1 WHERE [Type] = 1
UNION ALL
SELECT *, 2 AS SetID FROM table2
)
,cte2 as (
SELECT *,
RANK() OVER (PARTITION BY [Type], [Parent] ORDER BY SetID) FROM cte) rk
FROM cte
)
SELECT * FROM cte2 WHERE rk = 1