Pergunta

Existe uma maneira de reescrever uma instrução Transact SQL que usa um caso em que a estrutura para fazer o mesmo sem usar o caso quando?

Eu estou usando um produto que tem um built-in designer de consulta e sua própria pseudo-SQL. Ele tem limitações sobre o que eu posso usar com o SQL Server e Oracle. Então, eu tenho esta coluna que, quando o banco de dados subjacente é Oracle, usa DECODE (que é suportado). No entanto, eu preciso fazê-lo funcionar com o SQL Server e CASE WHEN não é suportado.

A declaração Eu estou tentando converter é algo como

Decode (StatusColumn,  'Value 1',
Decode(Sign(Now()-TargetDateColumn)),1,'Past
Due', 'Outstanding'),  'Value 2',
Decode(Sign(Now()-TargetDateColumn)),1,'Past
Due', 'Outstanding'),  'Value 3',
Decode(Sign(Now()-TargetDateColumn)),1,'Past
Due', 'Outstanding'),  'Value 4')

Eu tenho um conjunto limitado de opções T-SQL para usar e CASE WHEN não é uma opção. Eu tenho IsNull e Coalesça, mas eu não tenho certeza se eles vão me ajudar com este.

Não se preocupe com os cálculos de data, aqueles são resolvidos.

Eu procurei o caso quando perguntas aqui, sem sucesso.

Obrigado!

Update:

Eu percebo que eu deveria ter dado mais detalhes sobre a razão para as limitações, pois isso é o recurso de um desenvolvedor e seria assumido que este é um produto de desenvolvimento. Não é.

Eu estou usando um produto de software empresarial que tem um built-in designer de consulta e sua própria pseudo-SQL. Ele tem limitações sobre o que eu posso usar com o SQL Server e Oracle. Basicamente, tudo o que não quebrar a análise do mecanismo de consulta integrado é jogo. Isso significa que todas as funções sancionados e expressões, além de todas as abstrações de dados (objetos internos que correspondem a uma tabela física em um banco de dados e outras consultas criadas com o produto), além de tudo, desde Oracle SQL ou Transact SQL que não quebrar explicitamente a análise .

A razão pela qual CASE WHEN não funciona para mim é que ele quebra a análise do pseudo-SQL pelo mecanismo de consulta.

Finalmente, eu gostaria de tentar:

  1. única consulta do produto Uso desenhador do SQL que passa a análise ou
  2. Use alguns recursos extras de o banco de dados SQL Server eo designer de consulta para fazê-lo.

Com base nas várias boas respostas que eu tenho, aqui é a abordagem que funcionou para mim, até agora.

Jason DeFontes sugeriu que eu poderia usar uma exibição de banco de dados para executar o caso quando as regras e que cai # 2 acima. Ele funciona para mim, porque a vista é bastante dinâmico que eu não tenho que fazer manutenção nele (ao contrário de tabelas de verdade do richartallent abordagem, que eu acredito que são perto de abordagem de Jason). sugestão de criação de uma função de Pascal iria no mesmo sentido, mas, provavelmente, quebrar o parse.

Então, eu criei uma visão banco de dados que faz todo o transformação com CASE WHEN e eu adicionei-lo para SQL da minha consulta, juntou-lo com o SQL existente e funcionou muito bem. Sei que provavelmente estou adicionando uma sobrecarga para o motor de banco de dados, uma vez que terá de recuperar os mesmos dados ajustados duas vezes (uma para a vista e um para a consulta), mas é um daqueles casos em que é quase um problema.

Dado que este "usar uma exibição para ofuscar ele" trabalhos de design para mim, eu me pergunto qual seria a abordagem mais eficiente:

  • Usar uma seleção com CASE WHEN;
  • Usando CTE (novamente, richardtallent);
  • Usando União Todos (HLGEM);
  • Usando Subqueries (MisterZimbu);

Eu ainda irá verificar a sugestão de Aramis Wyler, como provavelmente poderia cair em # 1 acima.

Por enquanto, a resposta de Jason foi aceito. Considerando que eu usei CASE WHEN na vista, talvez o título para a questão acabou sendo é mal escolhido. Eu levantei todo mundo que sugeria algo que ajudou no processo. Eu não sei se isso faz a diferença em sua reputação ou não, mas eu pensei que era a coisa agradável a fazer.

Mais uma vez, quero agradecer a todos por sua ajuda e pedir-lhe gentilmente para editar qualquer coisa sobre a questão que você caiu não é apropriado (é a minha primeira pergunta e Inglês é a minha segunda língua).

Foi útil?

Solução

Você pode mover a CASE / quando a lógica em uma vista, em seguida, ter a consulta ferramenta a vista?

Outras dicas

Você tem união todos disponíveis? Talvez você poderia escrever uma consulta para cada uma das condições com a condição do caso inthe onde cláusula e união los juntos.

Você pode escrever subqueries personalizados? Provavelmente não, se você não tem sequer acesso a caso quando, mas isso provavelmente funcionaria demasiado:

select
    ...,
    coalesce(c1.value, c2.value, c3.value, ..., <default value>)
from MyTable
left join (select <result 1> as value) c1 on <first condition>
left join (select <result 2> as value) c2 on <second condition>
left join (select <result 3> as value) c3 on <third condition>

Escreva uma função que realiza o cálculo usando CASE WHEN.

É feio e, dependendo do número de valores que você tem pode não ser viável. Mas estritamente falando, acho que algo como isso iria funcionar como tradução do segmento consulta acima:

selecione 'PastDue' de tablename onde Now ()> TargetDateColumn e (StatusColumn = 'Valor 1' ou StatusColumn = 'Valor 2' ou StatusColumn = 'Valor 3') union select 'Excelente', onde Now ()

Eu não sei exatamente o que eu entendo o seu código, mas isso deve dar-lhe uma ideia para uma abordagem diferente.

Em primeiro lugar, criar uma tabela:

CREATE TABLE StatusLookup(
   value nvarchar(255),
   datesign shortint,
   result varchar(255));

Agora, preenchê-lo com uma tabela de verdade (lotes de lógica repetido em aqui, aparentemente, talvez este deve ser duas tabelas de verdade com um CROSS JOIN entre eles):

INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 1', -1, 'Outstanding')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 1', 0, 'Outstanding')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 1', 1, 'Past Due')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 2', -1, 'Outstanding')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 2', 0, 'Outstanding')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 2', 1, 'Past Due')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 3', -1, 'Outstanding')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 3', 0, 'Outstanding')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 3', 1, 'Past Due')

Finalmente, junte-se e fornecer uma resposta padrão:

SELECT mytable.*, COALESCE(statuslookup.result, 'Value 4')
FROM
    mytable LEFT JOIN statuslookup ON
        statuslookup.value = StatusColumn
        AND statuslookup.datesign = Sign(Now()-TargetDateColumn)

Uma das principais vantagens dessa abordagem é que coloca a lógica de negócios em tabelas de dados, não o código, que é muitas vezes mais sustentável e extensível.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top