¿Cómo reutilizar columnas calculadas evitando duplicar la instrucción sql?


Tengo un montón de columnas calculadas y se repetean a sí mismas, una dentro de las otras, incluidas las sentencias cases anidadas.

Hay una versión realmente simplificada de algo que he buscado una manera de hacer.

SELECT 
    (1+2) AS A, 
    A + 3 AS B, 
    B * 7 AS C 
FROM MYTABLE

Gracias de antemano.

Author: Eduardo Maia, 2011-07-28

6 answers

Podrías intentar algo como esto.

SELECT 
    A.Val AS A, 
    B.Val AS B, 
    C.Val AS C 
FROM MYTABLE
  cross apply(select 1 + 2) as A(Val)
  cross apply(select A.Val + 3) as B(Val)
  cross apply(select B.Val * 7) as C(Val)
 20
Author: Mikael Eriksson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-28 20:01:04

No se puede hacer referencia a expresiones recién creadas haciendo referencia más tarde a sus alias de columna. Piense en toda la lista de selección como si se materializara al mismo tiempo o en orden aleatorio - A aún no existe cuando está tratando de hacer una expresión para crear B. Necesita repetir las expresiones - No creo que pueda hacer columnas calculadas "más simples" sin repetirlas, y las vistas son las mismas-tendrá que anidar cosas, como:

SELECT A, B, C = B * 7
FROM
(
  SELECT A, B = A + 3
  FROM 
  (
    SELECT A = (1 + 2)
  ) AS x
) AS y;

O repetir la expresión (pero supongo eso es lo que estás tratando de evitar).

 7
Author: Aaron Bertrand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-28 20:19:41

Otra opción si alguien todavía está interesado:

with aa(a) as ( select 1+2 ) 
, bb(b) as ( select a+3 from aa ) 
,cc(c) as ( select b*7 from bb) 
SELECT aa.a, bb.b, cc.c 
from aa,bb,cc
 5
Author: Elastep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-09 10:54:35

La única forma de "guardar" los resultados de tus cálculos sería usándolos en una subconsulta, de esa manera puedes usar A, B and C. Lamentablemente, no puede hacerse de otra manera.

 1
Author: Oscar Gomez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-28 19:55:08

Puede crear columnas calculadas para representar los valores que desea. Además, puede usar una vista si sus cálculos dependen de los datos de una tabla separada.

 1
Author: Bobby D,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-28 19:55:42

¿Quieres resultados calculados de tu tabla? En ese caso, puede colocar los cálculos relevantes en la función definida por el usuario con valor escalar y usarla dentro de su instrucción select.

O desea que los resultados calculados aparezcan como columnas en la tabla, luego use una columna calculada:

CREATE TABLE Test(
    ID INT NOT NULL IDENTITY(1,1),
    TimesTen AS ID * 10
)
 0
Author: Anders Abel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-10 13:56:04