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

Откуда:
Сообщений: 11
Подскажите, каким образом можно реализовать следующую выборку:

Имеется таблица, в которой есть поля:
id | one | two | three | four

и которая содержит данные вида:

1 | 8 | 14 | 18 | 0
------------------------
2 | 0 | 14 | 18 | 1
------------------------
3 | 8 | 15 | 17 | 0
------------------------
4 | 8 | 15 | 18 | 1

Необходимо сделать выборку таким образом, что бы выбрать значения совпадающие по всем полям, если таковые есть в таблице. Иначе, следует заменить не совпадающее значение поля one на запись со значением one = 0. Т.е. one = 0 - это значение по умолчанию для перечисленных полей two и three.

Получается, необходимо проверить есть ли записи в таблице, отвечающие полному совпадению значений по полям one, two, three - если есть, выбрать их, иначе выбрать на их место записи, где one = 0, а two и three равны искомым значениям.
2 ноя 09, 22:33    [7873911]     Ответить | Цитировать Сообщить модератору
 Re: Пересечение результатов выборки  [new]
Ozzy-Osbourne
Member

Откуда: Balashikha
Сообщений: 139
misho misho,

сначала Вы пишете "выбрать значения совпадающие по всем полям". Затем - что "необходимо проверить есть ли записи в таблице, отвечающие полному совпадению значений по полям one, two, three". Ладно, про id понятно, что его учитывать не надо. Но куда подевалось поле 'four' ?

В общем, если его просто забыли дописать, то попробуйте так:
declare @t table(id int, f1 int, f2 int,f3 int, f4 int)
insert into @t
select 1 , 8 , 14 , 18 , 0 union all
select 2 , 0 , 14 , 18 , 1 union all
select 3 , 8 , 15 , 17 , 0 union all
select 4 , 8 , 15 , 18 , 1
insert into @t
select 5 , 8 , 15 , 17 , 0 union all
select 6 , 1974, 1534415 , 1754445 , -892992 union all
select 7 , 2881, 8288225 , 7005211 , 9199191 union all
select 8 , 8271, 1188225 , 7005211 , 9199191 union all
select 9 , 1974, 1534415 , 1754445 , -892992 union all
select 10, 1974, 1534415 , 1754445 , -892992

select
			 id
			,f1x=isnull(hasDup*0+t1.f1,t0.f1z)
			,f2x=isnull(hasDup*0+t1.f2,t0.f2z)
			,f3x=isnull(hasDup*0+t1.f3,t0.f3z)
			,f4x=isnull(hasDup*0+t1.f4,t0.f4z)
from(
	select f1,f2,f3,f4,t.id,hasDup=abs(2+sign(x.id))
	from @t t
        outer apply(select top 1 id from @t tx where tx.id<>t.id and tx.f1=t.f1 and tx.f2=t.f2 and tx.f3=t.f3 and tx.f4=t.f4) x
)t1
join(select f1z=0,f2z=min(f2),f3z=min(f3),f4z=min(f4) from @t where f1=0) t0 on 1=1
order by id
Result:
+
idf1xf2xf3xf4x
1014181
2014181
3815170
4014181
5815170
6197415344151754445-892992
7014181
8014181
9197415344151754445-892992
10197415344151754445-892992


ЗЫ. На всякий случай, решил подстраховаться: из текста выходит, что запись с f1=0 должна быть ОДНОЙ, т.к. она - некий "эталон" для получения значений по умолчанию. Поэтому обратите внимание, что сделано внутри таблицы t0:
select f1z=0,f2z=min(f2),f3z=min(f3),f4z=min(f4) from @t where f1=0
Это не даст увеличиться числу строк в итоговой выборке, если вдруг появятся две и более записей с f1=0.
2 ноя 09, 23:49    [7874061]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить