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

Откуда:
Сообщений: 122
задача, наверное, типичная. но мне решение не приходти.. а я его жду,жду. заждался. помогите, пож-ста.
имеется mssql2005.
CREATE TABLE T_events(id int IDENTITY(1,1)NOT NULL, ev_name nvarchar(32)NOT NULL, CONSTRAINT [PK_T_events] PRIMARY KEY CLUSTERED([id] ASC))
CREATE TABLE t_days(id int NOT NULL, ievent int, day nvarchar(32) NOT NULL)
в течение дня происходят какие-то события. и так день за днем.
допустим, надо выбрать все дни, когда я ел рыбу а меня тёща пилила цианистым калием, при этом исключив дни те, когда когда я пил пиво, пурген, ел шпиг и благодарил тёщу...

ну, выборка "включения" простая (ниже - это типа,псевдокод).
select * from t_days d
inner join t_events e on e.id=d.ievent
where d.ievent in ('я ел рыбу', 'меня пилила тёща')

а вот как исключить ненужное? не представляю. заранее благодарю.
9 ноя 09, 17:35    [7903763]     Ответить | Цитировать Сообщить модератору
 Re: исключающая выборка из выборки  [new]
iljy
Member

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

EXCEPT, INTERSECT
9 ноя 09, 17:37    [7903779]     Ответить | Цитировать Сообщить модератору
 Re: исключающая выборка из выборки  [new]
vv40in
Member

Откуда:
Сообщений: 122
ищвините, в коде я вижу ошибки. правильнее так:
select * from t_days d
inner join t_events e on e.id=d.ievent
where e.ev_name in ('я ел рыбу', 'меня пилила тёща')
9 ноя 09, 17:38    [7903785]     Ответить | Цитировать Сообщить модератору
 Re: исключающая выборка из выборки  [new]
iljy
Member

Откуда:
Сообщений: 8711
vv40in
ищвините, в коде я вижу ошибки. правильнее так:
select * from t_days d
inner join t_events e on e.id=d.ievent
where e.ev_name in ('я ел рыбу', 'меня пилила тёща')

это ИЛИ.

автор

когда я ел рыбу а меня тёща пилила цианистым калием


Это И.

так что ошибки не в коде, а в логике.
9 ноя 09, 17:40    [7903810]     Ответить | Цитировать Сообщить модератору
 Re: исключающая выборка из выборки  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
vv40in
при этом исключив дни те, когда когда я
Если "при этом", то всё уже исключено вышеупомянутым IN
Если же надо просто исключить, то
d.ievent IS NULL OR d.ievent NOT IN('пил пиво','ел шпиг','благодарил тёщу')
Правда, я предположил, что Вам не нужны также неопознанные события (d.ievent IS NULL)
Хотя, кто знает...
9 ноя 09, 17:43    [7903833]     Ответить | Цитировать Сообщить модератору
 Re: исключающая выборка из выборки  [new]
Anddros
Member

Откуда:
Сообщений: 1077
and not exists(select 1 from t_events e2 on e2.id=d.ievent where e2.ev_name in ('я пил пиво, пурген, ел шпиг и благодарил тёщу'))
9 ноя 09, 17:43    [7903839]     Ответить | Цитировать Сообщить модератору
 Re: исключающая выборка из выборки  [new]
vv40in
Member

Откуда:
Сообщений: 122
iljy
EXCEPT, INTERSECT

не понял. т.е. не получилось. вот пример:
declare @ev TABLE (id int IDENTITY(1,1)NOT NULL, ev_name nvarchar(32)NOT NULL)
declare @days TABLE (id int IDENTITY(1,1)NOT NULL, ievent int NOT NULL, nday nvarchar(32) NOT NULL)

insert @ev(ev_name) values('ел')
insert @ev(ev_name) values('пил')
insert @ev(ev_name) values('работал')
insert @ev(ev_name) values('отдыхал')

insert @days(ievent,nday) values(1,'пнд')
insert @days(ievent,nday) values(3,'пнд')
insert @days(ievent,nday) values(2,'втр')
insert @days(ievent,nday) values(3,'втр')
insert @days(ievent,nday) values(3,'срд')
insert @days(ievent,nday) values(1,'чтв')
insert @days(ievent,nday) values(3,'чтв')
insert @days(ievent,nday) values(2,'птн')
insert @days(ievent,nday) values(3,'птн')
insert @days(ievent,nday) values(2,'сбт')
insert @days(ievent,nday) values(4,'сбт')
insert @days(ievent,nday) values(1,'вск')
insert @days(ievent,nday) values(2,'вск')
insert @days(ievent,nday) values(4,'вск')

--вывести дни, когда (не работал) и (ел) и (пил), ('суб','вск')

select * from @days d
inner join @ev e on e.id=d.ievent

select * from @days d
inner join @ev e on e.id=d.ievent
where e.ev_name in ('ел', 'пил')
and e.ev_name NOT IN('работал')

select * from @days d
inner join @ev e on e.id=d.ievent
where e.ev_name in ('ел', 'пил')
EXCEPT 
select * from @days d
inner join @ev e on e.id=d.ievent
where e.ev_name in ('работал')
просто выборка:
1	1	пнд	1	ел
2 3 пнд 3 работал
3 2 втр 2 пил
4 3 втр 3 работал
5 3 срд 3 работал
6 1 чтв 1 ел
7 3 чтв 3 работал
8 2 птн 2 пил
9 3 птн 3 работал
10 2 сбт 2 пил
11 4 сбт 4 отдыхал
12 1 вск 1 ел
13 2 вск 2 пил
14 4 вск 4 отдыхал

NOT IN:
1	1	пнд	1	ел
3 2 втр 2 пил
6 1 чтв 1 ел
8 2 птн 2 пил
10 2 сбт 2 пил
12 1 вск 1 ел
13 2 вск 2 пил

результат с EXCEPT:
1	1	пнд	1	ел
3 2 втр 2 пил
6 1 чтв 1 ел
8 2 птн 2 пил
10 2 сбт 2 пил
12 1 вск 1 ел
13 2 вск 2 пил

это не есть правильно

Anddros
and not exists(select 1 from t_events e2 on e2.id=d.ievent where e2.ev_name in ('я пил пиво, пурген, ел шпиг и благодарил тёщу'))

не понял. или здесь ошибка (есть вероятность), или я не знаю (оч.болшая верояность) как и куда эту фразу приклеить. sql ругается на on
9 ноя 09, 18:36    [7904138]     Ответить | Цитировать Сообщить модератору
 Re: исключающая выборка из выборки  [new]
Anddros
Member

Откуда:
Сообщений: 1077
vv40in
не понял. или здесь ошибка (есть вероятность), или я не знаю (оч.болшая верояность) как и куда эту фразу приклеить. sql ругается на on
есть там ошибка, есть. Грубая и синтаксическая. :) Вместо 'on' должно быть 'where', а вместо 'where' - 'and'. Но это не решало ваших проблем. Уж больно кривая схема данных, как выяснилось после публикации Вами тестовых данных. Но это - Ваши проблемы. :)

Вот такого плана запрос вам нужен:
select nday 
from @days
where ievent in (select id from @ev where ev_name in ('ел', 'пил'))
except
select nday 
from @days
where ievent in (select id from @ev where ev_name in ('работал'))
9 ноя 09, 18:55    [7904213]     Ответить | Цитировать Сообщить модератору
 Re: исключающая выборка из выборки  [new]
vv40in
Member

Откуда:
Сообщений: 122
Anddros,
здОрово! спасибо!
9 ноя 09, 19:04    [7904249]     Ответить | Цитировать Сообщить модератору
 Re: исключающая выборка из выборки  [new]
Ozzy-Osbourne
Member

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

вот еще два варианта:
1) краткая информация о Вашем досуге:
select d.nday
 from @days d join @ev e on d.ievent=e.id 
cross apply(select r=case e.ev_name when 'работал' then 0 else 1 end)x
group by d.nday
having min(x.r)=1
nday
вск
сбт
2) подробная информация о Вашем досуге:
select id,ievent,nday,ev_name
from
(
  select d.id,d.ievent,d.nday,e.ev_name,m=min(x.r)over(partition by d.nday)
  from @days d join @ev e on d.ievent=e.id 
  cross apply(select r=case e.ev_name when 'работал' then 0 else 1 end)x
)t
where m=1
idieventndayev_name
121вскел
132вскпил
144вскотдыхал
102сбтпил
114сбтотдыхал
9 ноя 09, 20:23    [7904437]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить