Pregunta

¿Hay una manera de volver a escribir una instrucción de Transact SQL que utiliza un caso cuando la estructura para hacer lo mismo sin necesidad de utilizar el caso cuando?

Estoy usando un producto que tiene un diseñador de consultas incorporado y su propio pseudo-SQL. Tiene limitaciones en lo que puedo usar con SQL Server y Oracle. Así que tengo esta columna que, cuando la base de datos subyacente es Oracle, utiliza DECODE (que es soportado). Sin embargo, necesito para que funcione con SQL Server y caja cuando no es compatible.

La declaración que estoy tratando de convertir es algo así 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')

Tengo un conjunto limitado de opciones de T-SQL para usar y caja cuando no es una opción. Tengo EsNulo y se unen, pero no estoy seguro de si me van a ayudar con éste.

No se moleste con los cálculos de fecha, los que se resuelven.

He buscado en el caso cuando preguntas aquí, sin ningún resultado.

Gracias!

Actualización:

Me doy cuenta de que debería haber dado más detalles sobre la razón de las limitaciones, ya que se trata de recursos de un desarrollador y se asumiría que este es un producto de desarrollo. No lo es.

Estoy usando un producto de software empresarial que tiene un diseñador de consultas incorporado y su propio pseudo-SQL. Tiene limitaciones en lo que puedo usar con SQL Server y Oracle. Básicamente, todo lo que no se rompa el análisis del motor de consulta integrado es juego. Esto significa que todas las funciones sancionados y expresiones, además de todas las abstracciones de datos (objetos internos que corresponden a una tabla física en una base de datos y otras consultas creadas con el producto), además de todo, desde Oracle SQL o Transact SQL que no se rompe de forma explícita el análisis .

La razón por caso cuando no funciona para mí es que rompe el análisis de la pseudo-SQL por el motor de consulta.

Por último, me gustaría tratar de:

  1. Utilice únicamente la consulta del producto diseñador del SQL que pasa el análisis sintáctico o
  2. Utilice unos recursos adicionales de la base de datos de SQL Server y el diseñador de consultas para hacerlo.

Sobre la base de las varias buenas respuestas que me dieron, aquí está el enfoque que funcionó para mí, hasta ahora.

Jason DeFontes sugirió que podría utilizar una vista de base de datos para llevar a cabo el caso cuando las reglas y que cae en # 2 anterior. Funciona para mí porque es una visión lo suficientemente dinámica que no tengo que hacer el mantenimiento en él (a diferencia de enfoque de las tablas de verdad de richartallent, que creo que están cerca de enfoque de Jason). sugerencia de crear una función de Pascal iría en la misma línea, pero probablemente romper el análisis.

Así que creé una vista de base de datos que hace todo el caso cuando transformación con y he añadido a mi consulta SQL de, se unieron con el SQL existente y funcionó muy bien. Soy consciente de que probablemente estoy añadiendo una sobrecarga en el motor de base de datos, ya que tendrá que recuperar los mismo conjunto de datos dos veces (una para la vista y uno para la consulta), pero es uno de esos casos en los que es apenas un problema.

Dado que este "utilizar a fin de ocultar que" el diseño que funciona para mí, me pregunto cuál sería el enfoque más eficiente:

  • Uso de un selecto con CASO CUANDO;
  • Uso de CTE (de nuevo, richardtallent);
  • Uso Unión Todos (HLGEM);
  • Uso de subconsultas (MisterZimbu);

Todavía comprobaré la sugerencia de Aramis Wyler, ya que probablemente podría caer en # 1 arriba.

Por ahora, se aceptó la respuesta de Jason. Teniendo en cuenta que utilicé caso cuando en la vista, tal vez el título de la cuestión terminó siendo está mal elegido. Me subí a todo el mundo que sugería algo que ayudó en el proceso. No sé si eso hace la diferencia en su reputación o no, pero pensé que era lo agradable de hacer.

Una vez más, quiero agradecer a todos por su ayuda y pedirle que tenga que editar nada sobre la cuestión que se cayó no es apropiado (es mi primera pregunta y Inglés es mi segunda lengua).

¿Fue útil?

Solución

Se puede mover el CASE / Cuando la lógica en una visión, y luego tener la consulta herramienta de la vista?

Otros consejos

¿Tiene la unión todos disponibles? Tal vez usted podría escribir una consulta para cada una de las condiciones con las condiciones del caso enla cláusula where y la unión entre sí.

Se puede escribir subconsultas personalizados? Probablemente no si ni siquiera tiene acceso a caso cuando, pero esto probablemente funcionaría también:

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>

Escribir una función que lleva a cabo el cálculo utilizando CASO CUANDO.

Es feo y en función del número de valores que tienen puede que no sea viable. Pero estrictamente hablando, creo que algo como esto funcionaría como traducción del segmento consulta anterior:

seleccione 'de atrasado' de nombre de tabla donde ahora ()> TargetDateColumn y ( 'Valor 1' StatusColumn = o StatusColumn = 'Valor 2' o StatusColumn = 'Valor 3')   Unión seleccionar 'Sobresaliente' donde ahora ()

No estoy muy seguro de entender su código, pero esto debe darle una idea para un enfoque diferente.

En primer lugar, crear una tabla:

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

Ahora, rellenarla con una tabla de verdad (un montón de lógica repetida en aquí al parecer, tal vez esto debe ser de dos tablas de verdad con una combinación cruzada entre ellos):

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')

Por último, unir y proporcionar una respuesta por defecto:

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

Una de las ventajas clave de este enfoque se pone la lógica de negocio en las tablas de datos, no código, que a menudo es más fácil de mantener y extensible.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top