В настоящее время я работаю над особенно сложным прецедентом. Упрощение ниже:Выполнение подзапросов Sql functions
Во-первых, запись клиента имеет отношение «много-к-одному» с набором услуг, то есть один клиент может иметь несколько связанных с ним служб.
Внутри моего триггера я пишу запрос, который возвращает идентификатор клиента на основе определенных критериев. Эти критерии являются следующими,
- Если по крайней мере одна услуги типа В, и никаких услуг типа А не существуют, обратный идентификатор
- Если по крайней мере одна услуги типа С, и нет услуги типа в или а есть, возвращение идентификатор
- Если по крайней мере один сервис типа D, и никаких услуг типа с или в, или а не существуют, удостоверение личности возвращения
и мой нынешний подход, чтобы сформировать запрос аналогичного к которому ниже
SELECT c.ClientId
FROM
Clients AS c
-- actually INNER JOIN is superfluous in this sample, but required for
-- other auxilliary criteria i have left out. illustrates relationship
-- between Clients and Services table
INNER JOIN Services AS s ON c.ClientId = s.ClientId
WHERE
-- has at least one service of type B, no A
(EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'B')) AND
NOT EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'A'))) OR
-- has at least one service of type C, no B, no A
(EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'C')) AND
NOT EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'B')) AND
NOT EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'A'))) OR
-- has at least one service of type D, no C, no B, no A
(EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'D')) AND
NOT EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'C')) AND
NOT EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'B')) AND
NOT EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'A')))
, где [dbo].[Get_ServicesByClientIdAndType]
- это функция, которая возвращает связанные службы для указанного идентификатора клиента и типа сервиса. Подобно
-- this query is actually significantly more complex than shown
-- below, but this illustrates use of parameters client id and
-- service type
SELECT s.ServiceType
FROM
Services AS s
WHERE
s.ClientId = @clientId AND
s.ServiceType = @serviceType
Предполагая, что это оптимальные способы выражения этого сценария использования, будет функционировать [dbo].[Get_ServicesByClientIdAndType]
подзапрос кэшировать или же изменение параметров службы требует новой оценки каждого вызова? [Я призываю эту вещь, как 9 раз !!! работает Sql Server 2005]
Я знаю, что Sql Server 2005 поддерживает некоторые оптимизации подзапроса, такие как результаты кэширования, но я не знаю наверняка, при каких обстоятельствах или как создавать мои подзапросы [или функции], такие как Я максимально использую возможности Sql Server.
EDIT: рассмотрел мои критерии выше, и не мог отпустить нытье чувство чего-то был выключен. Я играл с какой-то логикой в моей голове, и пришел с этим [гораздо проще] формулировками
SELECT c.ClientId
FROM
Clients AS c
INNER JOIN Services AS s ON c.ClientId = s.ClientId
WHERE
NOT EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'A')) AND
(EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'B')) OR
EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'C')) OR
EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'D')))
по существу, не существует сценария с участием B, что приведет к отказу, аналогично для C и D, так что любая конфигурация является приемлемым. мы только заботимся о том, чтобы А отсутствовал в любом выборе. Arg! Чарли Браун!
оставляя оба выражения для обзора, и я до сих пор очень ценю ответы, касающиеся определенных пользовательских функций производительности WRT SQL Server.
Ничего себе, очень круто. Это имеет смысл, по существу, табулировать события в одном подзапросе, а затем выбирать из этого. Я только переформулировал свои критерии в более простом, но эквивалентном выражении - единственный эффект на ваше решение - это более простое внешнее предложение WHERE 'WHERE A.ServiceA = 0 AND (A.ServiceB> 0 ИЛИ A.ServiceC> 0 ИЛИ A.ServiceD> 0) ' –