Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Как записать компактнее UNION EXCEPT INTERSECT  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4893
Господа,
Есть два варианта написания одного и того же запроса. (На практике запрос естественно сложнее). Цель: найти все различия между двумя запросами.

Как записать это компактнее? Хотелось бы как минимум, чтобы "SELECT A FROM A" и "SELECT A FROM B" не приходилось бы выполнять дважды.

 
WITH A AS
(
	SELECT A FROM (VALUES (1),(2),(3),(4),(5)) T(A)
), B AS 
(
	SELECT A FROM (VALUES (2),(3),(4),(5),(6)) T(A)
)
SELECT A FROM 
(
	SELECT A FROM A
	EXCEPT 
	SELECT A FROM B
) T1 

UNION ALL

SELECT A FROM 
(
	SELECT A FROM B
	EXCEPT 
	SELECT A FROM A
) T2


;WITH A AS
(
	SELECT A FROM (VALUES (1),(2),(3),(4),(5)) T(A)
), B AS 
(
	SELECT A FROM (VALUES (2),(3),(4),(5),(6)) T(A)
)
SELECT A FROM 
(
	SELECT A FROM A
	UNION
	SELECT A FROM B
) T1 

EXCEPT 

SELECT A FROM 
(
	SELECT A FROM B
	INTERSECT 
	SELECT A FROM A
) T2
15 ноя 16, 16:56    [19896988]     Ответить | Цитировать Сообщить модератору
 Re: Как записать компактнее UNION EXCEPT INTERSECT  [new]
invm
Member

Откуда: Москва
Сообщений: 9825
WITH A AS
(
	SELECT A FROM (VALUES (1),(2),(3),(4),(5)) T(A)
), B AS 
(
	SELECT A FROM (VALUES (2),(3),(4),(5),(6)) T(A)
)
select
 isnull(A.A, B.A)
from
 A full join
 B on b.A = A.A
where
 A.A is null or B.A is null;
15 ноя 16, 17:21    [19897122]     Ответить | Цитировать Сообщить модератору
 Re: Как записать компактнее UNION EXCEPT INTERSECT  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4893
invm
WITH A AS
(
	SELECT A FROM (VALUES (1),(2),(3),(4),(5)) T(A)
), B AS 
(
	SELECT A FROM (VALUES (2),(3),(4),(5),(6)) T(A)
)
select
 isnull(A.A, B.A)
from
 A full join
 B on b.A = A.A
where
 A.A is null or B.A is null;


Да так можно, а если полей много? Перечислять их все по 6 раз тоже проблема
15 ноя 16, 17:25    [19897141]     Ответить | Цитировать Сообщить модератору
 Re: Как записать компактнее UNION EXCEPT INTERSECT  [new]
buven
Member

Откуда:
Сообщений: 792
a_voronin,

Может merge into cte поможет? Тынц
15 ноя 16, 17:36    [19897191]     Ответить | Цитировать Сообщить модератору
 Re: Как записать компактнее UNION EXCEPT INTERSECT  [new]
aleks2
Guest
О! Конкурс на самый идиотский запрос?
Я победю.

SELECT distinct A FROM A
UNION all
SELECT distinct A FROM B
group by A
having COUNT(*) = 1 
15 ноя 16, 17:38    [19897200]     Ответить | Цитировать Сообщить модератору
 Re: Как записать компактнее UNION EXCEPT INTERSECT  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4893
aleks2,

Идея поинтересней, но вы её не протестировали. Вот так правильно

WITH A AS
(
	SELECT A FROM (VALUES (1),(2),(3),(4),(5)) T(A)
), B AS 
(
	SELECT A FROM (VALUES (2),(3),(4),(5),(6)) T(A)
)
SELECT A FROM 
(
	SELECT distinct A FROM A
	UNION all
	SELECT distinct A FROM B
) T
group by A
having COUNT(*) = 1
15 ноя 16, 17:48    [19897236]     Ответить | Цитировать Сообщить модератору
 Re: Как записать компактнее UNION EXCEPT INTERSECT  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4893
buven
a_voronin,

Может merge into cte поможет? Тынц


зачем Merge, если надо просто проверить отличия?
15 ноя 16, 17:50    [19897239]     Ответить | Цитировать Сообщить модератору
 Re: Как записать компактнее UNION EXCEPT INTERSECT  [new]
aleks2
Guest
a_voronin
aleks2,

Идея поинтересней, но вы её не протестировали. Вот так правильно

WITH A AS
(
	SELECT A FROM (VALUES (1),(2),(3),(4),(5)) T(A)
), B AS 
(
	SELECT A FROM (VALUES (2),(3),(4),(5),(6)) T(A)
)
SELECT A FROM 
(
	SELECT distinct A FROM A
	UNION all
	SELECT distinct A FROM B
) T
group by A
having COUNT(*) = 1


Для тестирования дурацких идей фсегда есть достаточное количество дурней.
15 ноя 16, 17:53    [19897244]     Ответить | Цитировать Сообщить модератору
 Re: Как записать компактнее UNION EXCEPT INTERSECT  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4893
aleks2,

Вопрос на самом деле практический. Тестировать чем отличалось "то, что было" от "того, что стало"
15 ноя 16, 18:00    [19897263]     Ответить | Цитировать Сообщить модератору
 Re: Как записать компактнее UNION EXCEPT INTERSECT  [new]
invm
Member

Откуда: Москва
Сообщений: 9825
a_voronin
Да так можно, а если полей много? Перечислять их все по 6 раз тоже проблема
Тут надо определится с критерием оптимизации: "писать поменьше кода" или "менее затратно при выполнении".

ЗЫ: Этот вариант не годится, если в каких-либо столбцах может содержаться null.
15 ноя 16, 18:04    [19897274]     Ответить | Цитировать Сообщить модератору
 Re: Как записать компактнее UNION EXCEPT INTERSECT  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
invm
a_voronin
Да так можно, а если полей много? Перечислять их все по 6 раз тоже проблема
Тут надо определится с критерием оптимизации: "писать поменьше кода" или "менее затратно при выполнении".

ЗЫ: Этот вариант не годится, если в каких-либо столбцах может содержаться null.
Какой именно? И как помешает NULL?
15 ноя 16, 18:39    [19897358]     Ответить | Цитировать Сообщить модератору
 Re: Как записать компактнее UNION EXCEPT INTERSECT  [new]
iljy
Member

Откуда:
Сообщений: 8711
invm,

че это не годится-то? все годится. И писать немного

WITH A AS
(
	SELECT A, B FROM (VALUES (1,null),(null,2),(3,1),(4,1),(5,2)) T(A,B)
), B AS 
(
	SELECT A, B FROM (VALUES (null,2),(3,1),(4,2),(5,1),(null,null)) T(A,B)
)
select isnull(A.A, B.A), ISNULL(A.B, B.B)
from
 (select A.*, 1 x from A) a  full join (select *, 1 x from B) b on exists (select A.* intersect select b.*)
where
 A.x is null or B.x is null;
15 ноя 16, 18:43    [19897371]     Ответить | Цитировать Сообщить модератору
 Re: Как записать компактнее UNION EXCEPT INTERSECT  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4893
iljy
invm,

че это не годится-то? все годится. И писать немного

WITH A AS
(
	SELECT A, B FROM (VALUES (1,null),(null,2),(3,1),(4,1),(5,2)) T(A,B)
), B AS 
(
	SELECT A, B FROM (VALUES (null,2),(3,1),(4,2),(5,1),(null,null)) T(A,B)
)
select isnull(A.A, B.A), ISNULL(A.B, B.B)
from
 (select A.*, 1 x from A) a  full join (select *, 1 x from B) b on exists (select A.* intersect select b.*)
where
 A.x is null or B.x is null;


Это уже ближе к теме
15 ноя 16, 18:51    [19897391]     Ответить | Цитировать Сообщить модератору
 Re: Как записать компактнее UNION EXCEPT INTERSECT  [new]
кролик-зануда
Guest
a_voronin
Тестировать чем отличалось "то, что было" от "того, что стало"

а если запросы отличаются только наличием/количеством повторяющихся строк?

WITH A AS
(
	SELECT A FROM (VALUES (1),(2),(3),(1),(5)) T(A)
), B AS 
(
	SELECT A FROM (VALUES (2),(3),(4),(5),(6)) T(A)
)
SELECT A,sum(x)dif FROM 
(
	SELECT  A,1x FROM A
	UNION all
	SELECT A,-1 FROM B
) T
group by A
having sum(x) <> 0
15 ноя 16, 20:44    [19897752]     Ответить | Цитировать Сообщить модератору
 Re: Как записать компактнее UNION EXCEPT INTERSECT  [new]
Alexander Us
Member

Откуда:
Сообщений: 1161
a_voronin,

чтобы найти соврадения/различия между двумя таблицами/запросами поробуйте мою процедуру. (надо раскрыть спойлер)

Пример использования:
create table T1(C1 int, C2 int)
create table T2(C1 int primary key, C2 int)

insert T1 values(0,0)
insert T1 values(0,0)
insert T1 values(1,1)
insert T1 values(1,1)
insert T1 values(2,2)
insert T1 values(3,3)
insert T1 values(4,null)

insert T2 values(1,1)
insert T2 values(2,2)
insert T2 values(3,3)
insert T2 values(4,4)


exec [sp_Compare] 
'select * from Tools.dbo.T1'
,
'select * from Tools.dbo.T2'
,
'not equal'
16 ноя 16, 00:17    [19898299]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить