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

Откуда:
Сообщений: 20504
Есть запросы A, B и C.
Если запрос A возвращает NULL, нужно выполнить запрос B, иначе запрос С.
При этом результат запроса A используется в качестве подзапроса в запросе C
Как-то так:
SELECT case when (A) is NULL then (B)
            else (C)
       end



Хотелось бы все выполнить одним запросом и не дёргать 2 раза запрос A на каждую строку результата.
8 май 15, 17:06    [17619269]     Ответить | Цитировать Сообщить модератору
 Re: Соединение двух запросов  [new]
Konst_One
Member

Откуда:
Сообщений: 11538
if (NOT EXISTS(select * from A))
Begin
   select * from B
End
Else
Begin
   select * from C
End
8 май 15, 17:08    [17619273]     Ответить | Цитировать Сообщить модератору
 Re: Соединение двух запросов  [new]
defragmentator
Member

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

нет.

В запросе C запрос A по условию используется так же
8 май 15, 17:10    [17619279]     Ответить | Цитировать Сообщить модератору
 Re: Соединение двух запросов  [new]
Konst_One
Member

Откуда:
Сообщений: 11538
ничего не понятно, что вы хотите . напишите что вы делаете конкретно и что у вас не получается
8 май 15, 17:11    [17619282]     Ответить | Цитировать Сообщить модератору
 Re: Соединение двух запросов  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
Konst_One
ничего не понятно, что вы хотите . напишите что вы делаете конкретно и что у вас не получается


Подробнее (A B C D - таблицы):
SELECT case when (SELECT F1 FROM A WHERE F2=D.F2) is NULL then (SELECT F3 FROM B WHERE F2=D.F2)
            else (SELECT F4 FROM C WHERE F2=D.F2)
       end
FROM D 
8 май 15, 17:19    [17619313]     Ответить | Цитировать Сообщить модератору
 Re: Соединение двух запросов  [new]
Konst_One
Member

Откуда:
Сообщений: 11538
LEFT JOIN откройте для себя
8 май 15, 17:20    [17619320]     Ответить | Цитировать Сообщить модератору
 Re: Соединение двух запросов  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
defragmentator
Konst_One
ничего не понятно, что вы хотите . напишите что вы делаете конкретно и что у вас не получается


Подробнее (A B C D - таблицы):
SELECT case when (SELECT F1 FROM A WHERE F2=D.F2) is NULL then (SELECT F3 FROM B WHERE F2=D.F2)
            else (SELECT F4 FROM C WHERE F2=D.F2)
       end
FROM D 


Нет, вот такая идея:


SELECT case when (SELECT F1 FROM A WHERE F2=D.F2) is NULL then (SELECT F3 FROM B WHERE F2=D.F2)
            else    (SELECT F1 FROM A WHERE F2=D.F2)    end
FROM D 


Тут один запрос 2 раза выполняется
8 май 15, 17:22    [17619328]     Ответить | Цитировать Сообщить модератору
 Re: Соединение двух запросов  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
Konst_One
LEFT JOIN откройте для себя

Это будет многократное извлечение ненужных данных
8 май 15, 17:23    [17619334]     Ответить | Цитировать Сообщить модератору
 Re: Соединение двух запросов  [new]
Konst_One
Member

Откуда:
Сообщений: 11538
с чего бы это?

SELECT 
	case 
		when A.F1 is NULL THEN B.F3
        else A.F1 
    end as [F]
FROM 
	D LEFT OUTER JOIN A ON A.F2=D.F2 
	LEFT OUTER JOIN B ON B.F2=D.F2
8 май 15, 17:26    [17619343]     Ответить | Цитировать Сообщить модератору
 Re: Соединение двух запросов  [new]
Konst_One
Member

Откуда:
Сообщений: 11538
можно даже проще

select ISNULL(A.F1,B.F3) as [F] ...
8 май 15, 17:28    [17619353]     Ответить | Цитировать Сообщить модератору
 Re: Соединение двух запросов  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
Konst_One
с чего бы это?

SELECT 
	case 
		when A.F1 is NULL THEN B.F3
        else A.F1 
    end as [F]
FROM 
	D LEFT OUTER JOIN A ON A.F2=D.F2 
	LEFT OUTER JOIN B ON B.F2=D.F2


Вот именно, мне не на каждой записи резалт - сета нужны данные из таблицы B.
А таблица B - это у меня нехилый запрос : (select f8 from e) as b
8 май 15, 17:28    [17619358]     Ответить | Цитировать Сообщить модератору
 Re: Соединение двух запросов  [new]
Konst_One
Member

Откуда:
Сообщений: 11538
вы тут всё больше придумываете.
уже давно бы выложили свой супер запрос и народ бы подсказал вам как сделать оптимальней.
8 май 15, 17:30    [17619369]     Ответить | Цитировать Сообщить модератору
 Re: Соединение двух запросов  [new]
Кот Матроскин
Member

Откуда: Москва
Сообщений: 8933
SELECT case when (SELECT F1 FROM A WHERE F2=D.F2) is NULL then (SELECT F3 FROM B WHERE F2=D.F2)
            else (SELECT F4 FROM C WHERE F2=D.F2)
       end
FROM D 


Очень плохой код - если хотя бы один из запросов вернет несколько строк, конструкция накроется медным тазом.
По Вашему вопросу - если запрос A у Вас должен возвращать ровно одну строку с одним полем - почему бы не занести этот результат в перменную, и вместо подзапроса в B и С использовать эту переменную?
8 май 15, 17:42    [17619421]     Ответить | Цитировать Сообщить модератору
 Re: Соединение двух запросов  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
Konst_One
вы тут всё больше придумываете.
уже давно бы выложили свой супер запрос и народ бы подсказал вам как сделать оптимальней.

SELECT 

case when
(
case when ((D.id_operation) = 1) then (SELECT idCPC FROM [dbo].rC WHERE [id_document] = D.[id_document])
     when ((D.id_operation) = 2) then (SELECT idCPC FROM [dbo].rD WHERE [id_document] = D.[id_document])
     else NULL
end
)
is NULL then P.sZnName
else 
(
SELECT PZ.sName
FROM dbo.infT1 PZ with (nolock) 
INNER JOIN dbo.[rCPProperty] rCPP with (nolock) ON PZ.idType = rCPP.idZn
WHERE (rCPP.idCreditProduct = 
(
case when ((D.id_operation) = 1) then (SELECT idCPC FROM [dbo].rC WHERE [id_document] = D.[id_document])
     when ((D.id_operation) = 2) then (SELECT idCPC FROM [dbo].rD WHERE [id_document] = D.[id_document])
     else NULL
end
)
) and (rCPP.idCreditProductPropertyZn = 9998)
)
end

FROM dbo.rDoc D with (nolock) 
LEFT JOIN vwDocProperty P ON (P.id_document = D.id_document) and (P.idPropertyZn = 9998) 
ORDER BY D.id_document;


Ну вот, несущественное убрал
8 май 15, 17:49    [17619447]     Ответить | Цитировать Сообщить модератору
 Re: Соединение двух запросов  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
Кот Матроскин
SELECT case when (SELECT F1 FROM A WHERE F2=D.F2) is NULL then (SELECT F3 FROM B WHERE F2=D.F2)
            else (SELECT F4 FROM C WHERE F2=D.F2)
       end
FROM D 



Очень плохой код - если хотя бы один из запросов вернет несколько строк, конструкция накроется медным тазом.
По Вашему вопросу - если запрос A у Вас должен возвращать ровно одну строку с одним полем - почему бы не занести этот результат в перменную, и вместо подзапроса в B и С использовать эту переменную?


Переменная - это значит уже не один запрос.
8 май 15, 17:50    [17619448]     Ответить | Цитировать Сообщить модератору
 Re: Соединение двух запросов  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
defragmentator, если в rC или в rD есть запись с нужным [id_document], можно быть уверенным, что она там - единственная? Если да, то вот так можно сократить:

select case when isnull(rC.idCPC, rD.idCPC) is null then P.sZnName
			else (	select	PZ.sName
					from	dbo.infT1 PZ with (nolock)
							inner join dbo.[rCPProperty] rCPP with (nolock) 
									on PZ.idType = rCPP.idZn
					where	rCPP.idCreditProduct = isnull(rC.idCPC, rD.idCPC)
						and rCPP.idCreditProductPropertyZn = 9998)
		end
from	dbo.rDoc D with (nolock)
		left  join vwDocProperty P 
				on P.id_document = D.id_document
				and P.idPropertyZn = 9998
		left  join [dbo].rC
				on rC.[id_document] = D.[id_document]
				and D.id_operation = 1
		left  join [dbo].rD
				on rD.[id_document] = D.[id_document]
				and D.id_operation = 2
order by D.id_document;
8 май 15, 18:16    [17619580]     Ответить | Цитировать Сообщить модератору
 Re: Соединение двух запросов  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
Minamoto
defragmentator, если в rC или в rD есть запись с нужным [id_document], можно быть уверенным, что она там - единственная? Если да, то вот так можно сократить:

select case when isnull(rC.idCPC, rD.idCPC) is null then P.sZnName
			else (	select	PZ.sName
					from	dbo.infT1 PZ with (nolock)
							inner join dbo.[rCPProperty] rCPP with (nolock) 
									on PZ.idType = rCPP.idZn
					where	rCPP.idCreditProduct = isnull(rC.idCPC, rD.idCPC)
						and rCPP.idCreditProductPropertyZn = 9998)
		end
from	dbo.rDoc D with (nolock)
		left  join vwDocProperty P 
				on P.id_document = D.id_document
				and P.idPropertyZn = 9998
		left  join [dbo].rC
				on rC.[id_document] = D.[id_document]
				and D.id_operation = 1
		left  join [dbo].rD
				on rD.[id_document] = D.[id_document]
				and D.id_operation = 2
order by D.id_document;


Да, запись единственная
8 май 15, 18:19    [17619593]     Ответить | Цитировать Сообщить модератору
 Re: Соединение двух запросов  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
Minamoto
defragmentator, если в rC или в rD есть запись с нужным [id_document], можно быть уверенным, что она там - единственная? Если да, то вот так можно сократить:

select case when isnull(rC.idCPC, rD.idCPC) is null then P.sZnName
			else (	select	PZ.sName
					from	dbo.infT1 PZ with (nolock)
							inner join dbo.[rCPProperty] rCPP with (nolock) 
									on PZ.idType = rCPP.idZn
					where	rCPP.idCreditProduct = isnull(rC.idCPC, rD.idCPC)
						and rCPP.idCreditProductPropertyZn = 9998)
		end
from	dbo.rDoc D with (nolock)
		left  join vwDocProperty P 
				on P.id_document = D.id_document
				and P.idPropertyZn = 9998
		left  join [dbo].rC
				on rC.[id_document] = D.[id_document]
				and D.id_operation = 1
		left  join [dbo].rD
				on rD.[id_document] = D.[id_document]
				and D.id_operation = 2
order by D.id_document;


Так неплохо. Вынести в ON дополнительный фильтр.
8 май 15, 18:22    [17619605]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить