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

Откуда:
Сообщений: 2
Привет! У меня есть маленькая задачка вот такого плана.
Есть таблица table, ну, например, такая:
name fruit
ВасяЯблоко
ПетяГруша
ЖораЯблоко
ВасяСлива
ПетяЯблоко
ЖораСлива

Задача - вывести список людей, у которых нет груши.
Помогите решить задачку.
Спасибо.
20 авг 12, 06:21    [13034882]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с простым SQL-запросом к базе данных  [new]
Sack
Member

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

Вам нужно из множества всех людей вычесть множество тех у которых есть груша.
20 авг 12, 06:49    [13034893]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с простым SQL-запросом к базе данных  [new]
kdi
Member

Откуда:
Сообщений: 2
SELECT name FROM table GROUP BY name MINUS (SELECT name FROM table GROU
P BY name,fruit HAVING fruit='Груша');
20 авг 12, 07:02    [13034898]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с простым SQL-запросом к базе данных  [new]
Lika95
Guest
я понимаю, что местные гуру предложат намного круче вариант, но вот мой такой:

create table #t1 (name nchar(10) null, fruit nchar(10) null)

insert into #t1 (name, fruit) 
		select N'Вася', N'Слива' union all
		select N'Петя', N'Яблоко' union all
		select N'Гена', N'Груша' union all 
		select N'Вася', N'Банан' union all
		select N'Петя', N'Персик' union all
		select N'Гена', N'Яблоко' union all
		select N'Вася', N'Яблоко' union all
		select N'Дима', N'Груша'

select * from #t1 where name not in (select name from #t1 where fruit = N'Груша')

drop table #t1
20 авг 12, 07:26    [13034906]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с простым SQL-запросом к базе данных  [new]
Lika95
Guest
простите, условия задачи невнимательно прочла

select name from #t1 where name not in (select name from #t1 where fruit = N'Груша') group by name
20 авг 12, 07:32    [13034908]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с простым SQL-запросом к базе данных  [new]
Sack
Member

Откуда:
Сообщений: 151
kdi
SELECT name FROM table GROUP BY name MINUS (SELECT name FROM table GROU
P BY name,fruit HAVING fruit='Груша');


Замените MINUS на EXCEPT и ваш вариант заработает.
Если оттуда группировки по-убирать и во втором селекте заменить HAVING на WHERE, то будет ни хуже чем вариант с not in.
20 авг 12, 07:40    [13034918]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с простым SQL-запросом к базе данных  [new]
Диклевич Александр
Member

Откуда:
Сообщений: 610
SELECT DISTINCT t.name FROM #t1 t WHERE NOT EXISTS(SELECT t1.name FROM #t1 t1 WHERE t1.fruit = N'Груша' AND t1.name = t.name);
20 авг 12, 11:01    [13035510]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с простым SQL-запросом к базе данных  [new]
Serg_77m
Member

Откуда: Донецк
Сообщений: 237
kdi,

задача не совсем корректна. В эту таблицу не попадут люди, у которых вообще ничего нет. Груши у них тоже нет, но мы о них из этой таблицы не узнаем.
20 авг 12, 12:24    [13036076]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с простым SQL-запросом к базе данных  [new]
Lika95
Guest
Serg_77m,

может я что-то не поняла, но вроде при любом способе решения все правильно?
а, кстати, а какое решения по мнению гуру наиболее оптимально и почему?

create table #t1 (name nchar(10) null, fruit nchar(10) null)
go
insert into #t1 (name, fruit) 
		select N'Вася', N'Слива' union all
		select N'Петя', N'Яблоко' union all
		select N'Гена', N'Груша' union all 
		select N'Вася', N'Банан' union all
		select N'Петя', N'Персик' union all
		select N'Гена', N'Яблоко' union all
		select N'Вася', N'Яблоко' union all
		select N'Дима', N'Груша' union all
		select N'Рома', Null

select * from #t1 order by name, fruit

-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
select name from #t1 where name not in (select name from #t1 where fruit = N'Груша') group by name

select name from #t1 group by name except (select name from #t1 where fruit=N'Груша'); 

select distinct t.name from #t1 t where not exists(select t1.name from #t1 t1 where t1.fruit = N'Груша' and t1.name = t.name);

drop table #t1
20 авг 12, 12:39    [13036173]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с простым SQL-запросом к базе данных  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
Lika95
Serg_77m,

может я что-то не поняла, но вроде при любом способе решения все правильно?
а, кстати, а какое решения по мнению гуру наиболее оптимально и почему?

create table #t1 (name nchar(10) null, fruit nchar(10) null)
go
insert into #t1 (name, fruit) 
		select N'Вася', N'Слива' union all
		select N'Петя', N'Яблоко' union all
		select N'Гена', N'Груша' union all 
		select N'Вася', N'Банан' union all
		select N'Петя', N'Персик' union all
		select N'Гена', N'Яблоко' union all
		select N'Вася', N'Яблоко' union all
		select N'Дима', N'Груша' union all
		select N'Рома', Null

select * from #t1 order by name, fruit

-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
select name from #t1 where name not in (select name from #t1 where fruit = N'Груша') group by name

select name from #t1 group by name except (select name from #t1 where fruit=N'Груша'); 

select distinct t.name from #t1 t where not exists(select t1.name from #t1 t1 where t1.fruit = N'Груша' and t1.name = t.name);

drop table #t1
Вам же сказали - ни одно!
Потому что люди - отдельно, груши - отдельно!
Должна быть таблица людей, таблица фруктов и таблица принадлежности фруктов людям.

P.S. В общем случае лучше использовать NOT EXISTS вместо NOT IN
И это по-любому лучше, чем EXCEPT
20 авг 12, 12:48    [13036265]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с простым SQL-запросом к базе данных  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
И что это за любовь к NCHAR()?
Такой тип действительно нужен довольно редко.
Хорошо использовать NVARCHAR()
20 авг 12, 12:51    [13036285]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с простым SQL-запросом к базе данных  [new]
Lika95
Guest
iap
Вам же сказали - ни одно!
Потому что люди - отдельно, груши - отдельно!
Должна быть таблица людей, таблица фруктов и таблица принадлежности фруктов людям.

P.S. В общем случае лучше использовать NOT EXISTS вместо NOT IN
И это по-любому лучше, чем EXCEPT


пардонте за оффтоп, но не предирайтесь вы так сильно к Васям и грушам, т.е. с позиции проектирования задачь, таблиц и т.п. - это конечно неправильно, но вместо Вась, груш тут могли быть просто числа, а я всего лишь пыталась решить задачку. и nchar тут тоже так к слову.
а вот за подсказаку в NOT EXISTS - большое спасибо :) я даже не подумала, а сразу сделала через NOT IN
20 авг 12, 13:17    [13036498]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить