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

Откуда: Харьков
Сообщений: 52
Здравствуйте,уважаемые форумчане!!!!!!!!!

БД кинотеатр.
Для каждого кинотеатра вывести имя посетителя который больше всего посещает

Есть таблицы
1)Cinema (ID_cinema int primary key not null,
Name varchar(30),...);
2)Movie
(ID_movie int primary key,
About_film varchar(100),...)
3)Viewer
(ID_viewer int primary key,
FIO varchar(50),...)
4) Seans
(ID_seans int ,
ID_movie int references Movie(ID_movie),
ID_cinema int references Cinema(ID_cinema),..)
5)Ticket
(ID_viewer int references Viewer(ID_viewer),
ID_seans int ,
DateOfSeans date,
Price int ,...)

И вот собственно мой запрос, вроде бы работает правильно, но как по мне он ужасен на вид))
(Задание еще раз: Для каждого кинотеатра вывести имя посетителя который больше всего посещает)
select Cinema.Name,FIO,count(Ticket.ID_viewer)
from ((Cinema inner join Seans on Seans.ID_cinema=Cinema.ID_cinema)inner join Ticket on Ticket.ID_seans=Seans.ID_seans)inner join Viewer on Viewer.ID_viewer=Ticket.ID_viewer
group by Cinema.Name,FIO
having EXISTS((select Cinema.Name,FIO,count(Ticket.ID_viewer)
from ((Cinema inner join Seans on Seans.ID_cinema=Cinema.ID_cinema)inner join Ticket on Ticket.ID_seans=Seans.ID_seans)inner join Viewer on Viewer.ID_viewer=Ticket.ID_viewer
group by Cinema.Name,FIO))



Заранее спасибо!
5 май 12, 10:51    [12512038]     Ответить | Цитировать Сообщить модератору
 Re: как улучшить запрос?  [new]
aleks2
Guest
Не мучайте сервер.
Для запроса достаточно соединения Seans и Ticket.
5 май 12, 11:03    [12512123]     Ответить | Цитировать Сообщить модератору
 Re: как улучшить запрос?  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
самый первое и важное имхо зайти в базу данных master открыть какую-нибудь системную процедуру и посмотреть как там все отформатировано, потом открыть еще несколько и еще раз внимательно посмотреть и запомнить. Повторить в своем коде.
5 май 12, 11:03    [12512133]     Ответить | Цитировать Сообщить модератору
 Re: как улучшить запрос?  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Dari_18,

Если мы боремся за красоту, то можете попробовать вот так (понятно, что не проверял)
with view_stats
as
(
select 
	s.ID_cinema,
	t.ID_viewer,
	cnt = count(*)
from
	Ticket t
	join Seans s on s.ID_seans = t.ID_seans
group by
	s.ID_cinema,
	t.ID_viewer
)
select 
	c.ID_cinema,
	c.Name,
	v.ID_viewer,
	v.FIO,
	vs.cnt
from
	Cinema c
	outer apply (select top(1) cnt, ID_viewer from view_stats vs where vs.ID_cinema = c.ID_cinema order by vs.cnt desc) vs
	left join Viewer v on v.ID_viewer = vs.ID_viewer
;
5 май 12, 11:23    [12512300]     Ответить | Цитировать Сообщить модератору
 Re: как улучшить запрос?  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
Или так. Привязал Viewer так сказать для проверки ссылочной целостности. Ну и потом один человек может себе хоть целый ряд выкупить, а посетил он только один сеанс
;with ViewerByCin(ID_viewer,cnt,ID_Cinema) as (
select
	v.ID_viewer
	,COUNT( *)
	,c.ID_Cinema
from	Cinema c	
		inner join Seans s on s.ID_cinema=c.ID_cinema
		inner join Ticket t on t.ID_seans = s.ID_seans
		inner join Viewer v on v.ID_viewer=t.ID_viewer
group by 	c.ID_Cinema,v.ID_viewer)
,VBCRanged(ID_viewer,cnt,ID_Cinema,rn) as(
select
	vbc.ID_viewer
	,vbc.cnt
	,vbc.ID_Cinema
	,DENSE_RANK() over (partition by vbc.ID_Cinema order by vbc.cnt desc)
from	ViewerByCin vbc
)

select 
	v.ID_Cinema
	,v.ID_viewer
	,v.cnt
from	VBCRanged v
where v.rn =1
5 май 12, 11:32    [12512375]     Ответить | Цитировать Сообщить модератору
 Re: как улучшить запрос?  [new]
Dari_18
Member

Откуда: Харьков
Сообщений: 52
SomewhereSomehow,

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

К сообщению приложен файл. Размер - 34Kb
5 май 12, 11:35    [12512408]     Ответить | Цитировать Сообщить модератору
 Re: как улучшить запрос?  [new]
Dari_18
Member

Откуда: Харьков
Сообщений: 52
Мистер Хенки,
ооо!спасибо большое!все работает!=))
5 май 12, 11:36    [12512422]     Ответить | Цитировать Сообщить модератору
 Re: как улучшить запрос?  [new]
Dari_18
Member

Откуда: Харьков
Сообщений: 52
уважаемые форумчане!

спасибо вам всем за помощь!!!!!!!!!!
5 май 12, 11:37    [12512432]     Ответить | Цитировать Сообщить модератору
 Re: как улучшить запрос?  [new]
Dari_18
Member

Откуда: Харьков
Сообщений: 52
Мистер Хенки,

только я не нашла что таое VBCRanged и DENSE_RANK, можете пожалуйста сказать для чего это?
5 май 12, 11:46    [12512499]     Ответить | Цитировать Сообщить модератору
 Re: как улучшить запрос?  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
Dari_18
Мистер Хенки,

только я не нашла что таое VBCRanged и DENSE_RANK, можете пожалуйста сказать для чего это?

VBCRanged это алиас -никакого значения не имеет, DENSE_RANK() это фунция про нее в справке написано
5 май 12, 11:51    [12512535]     Ответить | Цитировать Сообщить модератору
 Re: как улучшить запрос?  [new]
Dari_18
Member

Откуда: Харьков
Сообщений: 52
Мистер Хенки,

спасибо
5 май 12, 11:55    [12512569]     Ответить | Цитировать Сообщить модератору
 Re: как улучшить запрос?  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Dari_18,

просто поставьте точку с запятой после последней инструкции до with, ну или перед with, если вам так проще.
5 май 12, 12:06    [12512667]     Ответить | Цитировать Сообщить модератору
 Re: как улучшить запрос?  [new]
Dari_18
Member

Откуда: Харьков
Сообщений: 52
SomewhereSomehow, заработало)спасбио
5 май 12, 12:09    [12512692]     Ответить | Цитировать Сообщить модератору
 Re: как улучшить запрос?  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
SomewhereSomehow
Dari_18,

просто поставьте точку с запятой после последней инструкции до with, ну или перед with, если вам так проще.

а случай когда посетитель выкупает несколько мест?Ведь задание
 Для каждого кинотеатра вывести имя посетителя который больше всего посещает
а не больше всего покупает билетов ))
5 май 12, 12:12    [12512713]     Ответить | Цитировать Сообщить модератору
 Re: как улучшить запрос?  [new]
aleks2
Guest
Мистер Хенки
SomewhereSomehow
Dari_18,

просто поставьте точку с запятой после последней инструкции до with, ну или перед with, если вам так проще.

а случай когда посетитель выкупает несколько мест?Ведь задание
 Для каждого кинотеатра вывести имя посетителя который больше всего посещает
а не больше всего покупает билетов ))


Ну... эта такой эвфемизм. Кинотеатру то пофег, что не ходил - лиш бы купил.
5 май 12, 12:52    [12512994]     Ответить | Цитировать Сообщить модератору
 Re: как улучшить запрос?  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Мистер Хенки
SomewhereSomehow
Dari_18,

просто поставьте точку с запятой после последней инструкции до with, ну или перед with, если вам так проще.

а случай когда посетитель выкупает несколько мест?Ведь задание
 Для каждого кинотеатра вывести имя посетителя который больше всего посещает
а не больше всего покупает билетов ))

В таком случае потребуется учитывать на сеансе только уникальных посетителей (правда можно купить и не прийти). Но я не думаю, что это имелось ввиду.
И кстати не понимаю, разве ваш запрос это учитывает?
5 май 12, 13:26    [12513285]     Ответить | Цитировать Сообщить модератору
 Re: как улучшить запрос?  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
SomewhereSomehow
В таком случае потребуется учитывать на сеансе только уникальных посетителей (правда можно купить и не прийти). Но я не думаю, что это имелось ввиду.
И кстати не понимаю, разве ваш запрос это учитывает?

подловили да. не учитывает, т.е. то что я запостил не учитывает. Если это принципиально для решения задачи (считать не билеты, а посещения одним человеком) то надо count(distinct v.ID_viewer) вместо count(*)
5 май 12, 13:30    [12513317]     Ответить | Цитировать Сообщить модератору
 Re: как улучшить запрос?  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
Мистер Хенки
SomewhereSomehow
В таком случае потребуется учитывать на сеансе только уникальных посетителей (правда можно купить и не прийти). Но я не думаю, что это имелось ввиду.
И кстати не понимаю, разве ваш запрос это учитывает?

подловили да. не учитывает, т.е. то что я запостил не учитывает. Если это принципиально для решения задачи (считать не билеты, а посещения одним человеком) то надо count(distinct v.ID_viewer) вместо count(*)

ой фигню какую то написал. Картинка с другого сайта.
5 май 12, 13:41    [12513400]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить