Au début (ou re-commandé) réutilisation des colonnes dérivées dans une requête - est valide cette ANSI SQL?
-
20-09-2019 - |
Question
Est-ce valide ANSI SQL:
SELECT 1 AS X
,2 * X AS Y
,3 * Y AS Z
Parce que Teradata (12) peut le faire, ainsi que cela (oui, fou est pas):
SELECT 3 * Y AS Z
,2 * X AS Y
,1 AS X
Mais SQL Server 2005 requiert quelque chose comme ceci:
SELECT X
,Y
,3 * Y AS Z
FROM (
SELECT X
,2 * X AS Y
FROM (
SELECT 1 AS X
) AS X
) AS Y
La solution
Non, ce n'est pas valide ANSI. ANSI suppose que tous les éléments de clause SELECT sont évalués à la fois.
Et comme I'd've écrit dans SQL 2005:
SELECT *
FROM (SELECT 1 AS X) X
CROSS APPLY (SELECT 2 * X AS Y) Y
CROSS APPLY (SELECT 3 * Y AS Z) Z
;
Autres conseils
Il n'a pas besoin d'être laide que dans SQL Server 2005+. Voilà pourquoi Microsoft a introduit CTEs:
WITH T1 AS (SELECT 1 AS X),
T2 AS (SELECT X, 2 * X AS Y FROM T1)
SELECT X, Y, 3 * Y AS Z FROM T2
Ou vous pouvez utiliser CROSS APPLY
comme Rob démontre -. Qui peut ou peut ne pas fonctionner pour vous en fonction des spécificités de la requête
J'avoue que ce n'est pas aussi propre que de Teradata, mais il est loin d'être aussi mauvais que la version sous-requête, et l'exemple Teradata d'origine dans votre question est certainement pas partie de la norme SQL-92.
Je voudrais aussi ajouter que dans votre exemple original, les colonnes X
, Y
et Z
ne sont pas, techniquement, colonnes dérivées comme vous les appelez. Au moins aussi loin que Microsoft et ANSI sont concernés, ils sont juste alias , et un alias ne peut pas se référer à un autre alias jusqu'à ce qu'il devienne effectivement une colonne (grâce à une sous-requête ou CTE).