Eu criei um envolvido CTE
, sem recursão, mas com várias seleções sendo feitas à medida que processa a lógica de negócios do requisito. No entanto, fui informado de que a lógica necessária para o cenário em que nenhuma linha é retornada deve, em vez disso, retornar todas as linhas encontradas em uma das seleções intermediárias CTE
em vez da operação final.
Como isso pode ser alcançado?
Observe que o exemplo a seguir é a interpretação básica do meu processo e a operação em questão ocorre depois que várias seleções CTE em cascata são feitas e essencialmente encadeadas.
Exemplo (conforme encontrado em SQLFiddle )
Em uma tabela de usuário, existem dois registros onde os ids de UserId
s são 1
e 2
. O primeiro CTE
s select TargetUsers
não retornará nenhuma linha que exija o terceiro CTE, ComputeWithUsers
, para usar o AllUsers
.
WITH TargetUsers AS
(
SELECT *
FROM Users
WHERE UserId > 5
)
, AllUsers AS
(
SELECT * FROM Users
)
, ComputeWithUsers
(
-- This CTE will determine it needs to use `AllUsers` and not `TargetUsers`
)
Ou existe uma maneira de tornar a TargetUsers
seleção inteligente o suficiente para extrair todos os usuários quando sua operação principal não retornar nenhuma linha?
Aqui está a maneira que eu faria isso, assumindo que "faça tudo em uma consulta" não é apenas um requisito artificial e sem sentido.
Se "faça tudo em uma consulta" for um requisito difícil e você não puder usar uma tabela #temp, ou se realmente tiver uma lógica complexa que burlou de nós e/ou não quiser repetir, então você 'vai ter que pagar por essas escolhas no desempenho, eu tenho medo. Parece que deve ser bastante eficiente, mas haverá mais acessos à tabela base do que a maioria das pessoas esperaria / esperaria:
Na verdade, se o UserID for a chave primária e o filtro realmente estiver no UserID, isso pode ser melhor da seguinte maneira (mas você terá que verificar os planos para ver, depende de vários fatores):
Espero que suas consultas estejam usando práticas abaixo do ideal devido à simplificação, e não assim na produção, mas dê uma lida:
Supondo que o desempenho seja aceitável, você pode usar o seguinte como um meio de obter todos os usuários quando o filtro inicial não retornar nenhum resultado.
Você está apenas definindo um OR artificial que permitirá que todos os registros passem pelo filtro se a seleção de base não retornar nada.