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

Откуда: Москва
Сообщений: 5381
Подскажите, пжл. Есть запрос
	select
		ServiceName,
		count(*) as VisitCnt,
		isnull(sum(K), 0.0) as UetSum,
		isnull(sum(Cost), 0.0) as ServSum,
		count(dictinct idPatient) as PatientCnt
	from view_GoodServitmDent Servitm
	where
		DateTalon between '20090901' and '20090930'
	group by idService, ServiceName
	order by 1
Теперь правило подсчета количества посещений (VisitCnt) поменялось. Надо что то вроде такого
		count(distinct idPatient, idDoctor, DateVisit) as VisitCnt,
Но так запрещено синтаксисом SQL. Как можно сделать сие? В голову ничего кроме подзапроса не приходит, но это будет громоздко, поскольку секцию WHERE я тут упростил.
24 ноя 09, 11:08    [7968669]     Ответить | Цитировать Сообщить модератору
 Re: Хитрый COUNT(DISTINCT ...)  [new]
an0nym
Member

Откуда:
Сообщений: 7076
Senya_L
Подскажите, пжл. Есть запрос
	select
		ServiceName,
		count(*) as VisitCnt,
		isnull(sum(K), 0.0) as UetSum,
		isnull(sum(Cost), 0.0) as ServSum,
		count(dictinct idPatient) as PatientCnt
	from view_GoodServitmDent Servitm
	where
		DateTalon between '20090901' and '20090930'
	group by idService, ServiceName
	order by 1
Теперь правило подсчета количества посещений (VisitCnt) поменялось. Надо что то вроде такого
		count(distinct idPatient, idDoctor, DateVisit) as VisitCnt,
Но так запрещено синтаксисом SQL. Как можно сделать сие? В голову ничего кроме подзапроса не приходит, но это будет громоздко, поскольку секцию WHERE я тут упростил.

count(distinct idPatient, idDoctor, DateVisit) as VisitCnt
замените на count(distinct idPatient || idDoctor || DateVisit) as VisitCnt (если ошибся в синтаксисе соединения строк для MS SQL - поправьте сами)
24 ноя 09, 11:10    [7968690]     Ответить | Цитировать Сообщить модератору
 Re: Хитрый COUNT(DISTINCT ...)  [new]
aleks2
Guest
Senya_L
Подскажите, пжл. Есть запрос
	select
		ServiceName,
		count(*) as VisitCnt,
		isnull(sum(K), 0.0) as UetSum,
		isnull(sum(Cost), 0.0) as ServSum,
		count(dictinct idPatient) as PatientCnt
	from view_GoodServitmDent Servitm
	where
		DateTalon between '20090901' and '20090930'
	group by idService, ServiceName
	order by 1
Теперь правило подсчета количества посещений (VisitCnt) поменялось. Надо что то вроде такого
		count(distinct idPatient, idDoctor, DateVisit) as VisitCnt,
Но так запрещено синтаксисом SQL. Как можно сделать сие? В голову ничего кроме подзапроса не приходит, но это будет громоздко, поскольку секцию WHERE я тут упростил.


count(distinct cast(idPatient as varchar(4))+cast(idDoctor as varchar(4)), cast(DateVisit as varchar(4)))
24 ноя 09, 11:10    [7968697]     Ответить | Цитировать Сообщить модератору
 Re: Хитрый COUNT(DISTINCT ...)  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
an0nym
count(distinct idPatient || idDoctor || DateVisit) as VisitCnt (если ошибся в синтаксисе соединения строк для MS SQL - поправьте сами)
Тогда уж
count(distinct STR(idPatient,11)+STR(idDoctor,11)+CONVERT(CHAR(8),DateVisit,112)) as VisitCnt
При этом предполагаю, что
idPatient INT, idDoctor INT, DateVisit DATETIME
На самом деле, derived table нагляднее и лучше. IMHO. Слово "громоздко" в данном контексте непонятно.

Вместо derived table можно и CTE использовать, если версия позволяет.
24 ноя 09, 11:17    [7968771]     Ответить | Цитировать Сообщить модератору
 Re: Хитрый COUNT(DISTINCT ...)  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
Спасибо за помощь. Работает :)

2iap,

Громоздко - это так
	select
		ServiceName,
		count(*) as VisitCnt,
		isnull(sum(K), 0.0) as UetSum,
		isnull(sum(Cost), 0.0) as ServSum,
		count(distinct Servitm.idPatient) as PatientCnt
	from view_GoodServitmDent Servitm
	where
		DateTalon between @DateStart and @DateEnd
		and (@idLpu is null or idLpu = @idLpu)
		and (@idWork is null or idWorks = @idWork)
		and (@idSection is null or idSection = @idSection)
		and (@TerrString is null or exists (
			select * from dbo.fnParseWordList(@TerrString, ';') WS
				join Medical on Servitm.idPatient = Medical.idPatient and WS.Word = Medical.Territorial 
			)
		)
		and (@IsStranger is null or IsStranger = @IsStranger)
	group by idService, ServiceName
Если сделать подзапросом, то придется все предикаты повторять в подзапросе + соединение по idService и ServiceName.
24 ноя 09, 11:32    [7968893]     Ответить | Цитировать Сообщить модератору
 Re: Хитрый COUNT(DISTINCT ...)  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
iap
Вместо derived table можно и CTE использовать, если версия позволяет.
Снимаю шляпу. В очередной раз :)
Попробовал вариант с derrived table.
select
	ServiceName,
	sum(VisitCnt) as VisitCnt,
	sum(UetSum) as UetSum,
	sum(ServSum) as ServSum,
	sum(PatientCnt) as PatientCnt
from (
	select
		idService,
		ServiceName,
		count(*) as VisitCnt,
		isnull(sum(K), 0.0) as UetSum,
		isnull(sum(Cost), 0.0) as ServSum,
		count(idPatient) as PatientCnt
	from view_GoodServitmDent Servitm
	where
		DateTalon between '20090901' and '20090930'
	group by idService, ServiceName, idPatient, idDoctor, DateVisit
) A
group by idService, ServiceName
order by 1
Оценка стоимости выполнения на 0,005 меньше , но, что важнее, это безопаснее, имхо. Есть данные из старой БДи не удивлюсь, если там IDшники вылазят и за 11 исмволов в длину. Тип всех idXXX - numeric(18, 0)
24 ноя 09, 11:52    [7969122]     Ответить | Цитировать Сообщить модератору
 Re: Хитрый COUNT(DISTINCT ...)  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
Ошибка есть, исправлюсь сам
	sum(VisitCnt) as VisitCnt,
следует заменить на
	count(VisitCnt) as VisitCnt,
24 ноя 09, 12:00    [7969208]     Ответить | Цитировать Сообщить модератору
 Re: Хитрый COUNT(DISTINCT ...)  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Senya_L
Есть данные из старой БДи не удивлюсь, если там IDшники вылазят и за 11 исмволов в длину. Тип всех idXXX - numeric(18, 0)
А что мешает писать вместо 11 18?
24 ноя 09, 12:10    [7969301]     Ответить | Цитировать Сообщить модератору
 Re: Хитрый COUNT(DISTINCT ...)  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
iap
Senya_L
Есть данные из старой БДи не удивлюсь, если там IDшники вылазят и за 11 исмволов в длину. Тип всех idXXX - numeric(18, 0)
А что мешает писать вместо 11 18?
Ничего. Просто мне не нравятся агрегаты по вычисляемым выражениям. Фигово они оптимизуируются.

ЗЫ. Вы теперь защищаете подход, который недавно критиковали? ;)
24 ноя 09, 12:13    [7969339]     Ответить | Цитировать Сообщить модератору
 Re: Хитрый COUNT(DISTINCT ...)  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Senya_L
iap
Senya_L
Есть данные из старой БДи не удивлюсь, если там IDшники вылазят и за 11 исмволов в длину. Тип всех idXXX - numeric(18, 0)
А что мешает писать вместо 11 18?
Ничего. Просто мне не нравятся агрегаты по вычисляемым выражениям. Фигово они оптимизуируются.

ЗЫ. Вы теперь защищаете подход, который недавно критиковали? ;)
Нет. Просто удивило замечание про 11 символов.
Идея же не в них, а в выравнивании длин строк перед конкатенацией.
24 ноя 09, 12:17    [7969376]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить