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

Откуда:
Сообщений: 271
При результате Null выражения (SELECT sum(k.SumKB) FROM [data].[dbo].[kb] k where t.ContractNumber=k.ContractNumber and t.Vid=k.Vid) запрос не выгружает данные по договору даже если имеются записи по выражениям sum(t.[76]) и (SELECT sum(l.SumCompensation) FROM [data].[dbo].[loss_opl] l where t.ContractNumber=l.ContractNumber and t.Vid=l.Vid).
Как нужно перестроить запрос, чтобы при получении значения Null с любого вложенного запроса данные по договору все равно выгружались в результат?


DECLARE @Datefrom date, @Datetill date;
SET  @Datefrom = '20141001'
SET  @Datetill = '20141030';   

	SELECT
	       t.ContractNumber as 'Договор'
		  , sum(t.[76]) as 'Начислено'
		  ,(SELECT sum(l.SumCompensation) FROM [data].[dbo].[loss_opl] l where t.ContractNumber=l.ContractNumber and t.Vid=l.Vid) as 'Сумма возмещения'
		  ,(SELECT sum(k.SumKB) FROM [data].[dbo].[kb] k where t.ContractNumber=k.ContractNumber and t.Vid=k.Vid) as 'Сумма KB'
		  ,( sum(t.[76]) - (SELECT sum(l.SumCompensation) FROM [data].[dbo].[loss_opl] l where t.ContractNumber=l.ContractNumber and t.Vid=l.Vid)
		  -(SELECT sum(k.SumKB) FROM [data].[dbo].[kb] k where t.ContractNumber=k.ContractNumber and t.Vid=k.Vid)) as 'Результат'
		  FROM [data].[dbo].[76] t
	 	 WHERE t.DateEnd between @Datefrom and  @Datetill and
		 GROUP BY 
		   t.ContractNumber
		  	HAVING (sum(t.[76]) <= ((SELECT sum(l.SumCompensation) FROM [data].[dbo].[loss_opl] l where t.ContractNumber=l.ContractNumber and t.Vid=l.Vid)+
	(SELECT sum(k.SumKB) FROM [data].[dbo].[kb] k where t.ContractNumber=k.ContractNumber and t.Vid=k.Vid)))
23 сен 14, 13:11    [16609883]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по вложеному запросу  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
2viper2viper,

применить к указанным выражениям функцию ISNULL((SELECT ...),0)?

А вообще, запрос выглядит монструозно. Нехорошо это.
23 сен 14, 13:17    [16609946]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по вложеному запросу  [new]
2viper2viper
Member

Откуда:
Сообщений: 271
iap
2viper2viper,

применить к указанным выражениям функцию ISNULL((SELECT ...),0)?

А вообще, запрос выглядит монструозно. Нехорошо это.


Подскажите как можно изложить более корректно?
по смыслу, мне нужно выгрузить договора, у которых сумма платежа меньше чем сумма двух значений (кв и возм), данные по которым находятся в других таблицах
23 сен 14, 13:22    [16609992]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по вложеному запросу  [new]
Glory
Member

Откуда:
Сообщений: 104751
2viper2viper
Подскажите как можно изложить более корректно?

Не вычислять одно и тоже выражение несколько раз
У вас вот SELECT sum(l.SumCompensation) аж три раза вычисляется
23 сен 14, 13:30    [16610064]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по вложеному запросу  [new]
mrGuest
Guest
2viper2viper,

Используйте outer/cross apply

Например:
select	A.field3_sum
from	T1
	outer apply (
		select	sum(T2.field3)
		from	T2
		where	T2.field1 = T1.field1
	) as A (field3_sum)
where	A.field3_sum < 0
23 сен 14, 14:49    [16610658]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по вложеному запросу  [new]
2viper2viper
Member

Откуда:
Сообщений: 271
Спасибо mrGuest, таким путем решил задачу с использованием одного соединения


DECLARE @Datefrom date, @Datetill date;
SET  @Datefrom = '20141001'
SET  @Datetill = '20141030';   

	SELECT
	           t.ContractNumber as 'Договор'
		  ,sum(t.[76]) as 'Начислено'
		  ,u.Возмещение 
		  ,sum(t.[76]) - u.Возмещение  as 'Результат'
		  ,v.vid as 'Вид'

	 FROM [data].[dbo].[76] t
	 left join [Plans].[dbo].[vid_mask] v on t.vid like v.mask
	 outer apply (SELECT sum(l.SumCompensation) FROM [data].[dbo].[loss_opl] l where t.ContractNumber=l.ContractNumber and t.Vid=l.Vid) as u (Возмещение)
	 WHERE t.DateEnd between @Datefrom and  @Datetill 
	 GROUP BY 
		   t.ContractNumber
		  ,u.Возмещение 
	     	  ,v.vid 

	HAVING (sum(t.[76]) <= u.Возмещение )
	ORDER BY 	
		   t.DateEnd 
		  ,4 asc


Не нашел пример как применить два соединения outer apply
Использования такого запроса не возвращает строки с пустыми значениями функции sum(k.SumKB)
Возможно, запрос с двумя соединениями outer apply нужно составить по другому?

 

DECLARE @Datefrom date, @Datetill date;
SET  @Datefrom = '20141001'
SET  @Datetill = '20141030';   

	  SELECT
	       t.ContractNumber as 'Договор'
		  ,sum(t.[76]) as 'Начислено'
		  ,u.Возмещение 
		  ,y.КВ as 'КВ'
		  ,sum(t.[76]) - u.Возмещение -y.КВ  as 'Результат'
		  ,t.DateBegin as 'Дата начала'
		  ,t.DateEnd as 'Дата окончания'
		  ,v.vid as 'Вид'


	 FROM [data].[dbo].[76] t
	  left join [Plans].[dbo].[vid_mask] v on t.vid like v.mask
	  outer apply (SELECT sum(l.SumCompensation) FROM [data].[dbo].[loss_opl] l where t.ContractNumber=l.ContractNumber and t.Vid=l.Vid) as u (Возмещение)
	  outer apply (SELECT sum(k.SumKB) FROM [data].[dbo].[kb] k where t.ContractNumber=k.ContractNumber and t.Vid=k.Vid) as y (КВ)
	 WHERE t.DateEnd between @Datefrom a
	 GROUP BY 
		   t.ContractNumber
		  ,u.Возмещение 
		  ,y.КВ
		  ,t.DateBegin
		  ,t.DateEnd
		  ,v.vid 
	HAVING sum(t.[76]) <= (u.Возмещение+y.КВ )
	ORDER BY 	
		   t.DateEnd 
		  ,4 asc
24 сен 14, 10:49    [16614358]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по вложеному запросу  [new]
2viper2viper
Member

Откуда:
Сообщений: 271
Решение:

	HAVING sum(t.[76]) <= (u.Возмещение+COALESCE(y.КВ,0) )
25 сен 14, 12:49    [16620579]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить