MS SQL 2005 - ordenado por intercalación con falla subconsulta
-
28-09-2019 - |
Pregunta
Esta es una versión simplificada de una consulta real para mostrar el problema. Se puede ejecutar en la base de datos AdventureWorks de ejemplo:
SELECT Person.Address.*,
(SELECT TOP 1 [Name]
FROM Person.StateProvince
WHERE Person.StateProvince.StateProvinceId = Person.Address.StateProvinceId AND Person.StateProvince.TerritoryId IN (5, 6, 7)
ORDER BY Person.StateProvince.TerritoryId) AS [Name]
FROM Person.Address
ORDER BY [Name]
Esto funciona bien, pero mi problema es que si añado el cotejo de la orden por el campo, aparece un mensaje de error extraño:
SELECT Person.Address.*,
(SELECT TOP 1 [Name]
FROM Person.StateProvince
WHERE Person.StateProvince.StateProvinceId = Person.Address.StateProvinceId AND Person.StateProvince.TerritoryId IN (5, 6, 7)
ORDER BY Person.StateProvince.TerritoryId) AS [Name]
FROM Person.Address
ORDER BY [Name] COLLATE Chinese_PRC_CI_AI
Y el error es:
Msg 207, Level 16, State 1, Line 7
Invalid column name 'Name'.
La consulta con la cláusula de intercalación funciona bien si no hay sub consulta, pero necesito que sea así (por una razón complicado, pero por favor créeme:)).
¿Alguien sabe por qué esta consulta falla, y lo que puede ser una posible solución? Es esto un error?
Gracias! Adam
Solución
SQL Server no permite hacer referencia a columnas por alias en la cláusula ORDER BY. Por ejemplo, esto no funcionará:
select id+1 as x from MyTable order by x
Pero se puede arreglar eso mediante la repetición de la definición de columna:
select id+1 as x from MyTable order by id+1
o utilizando una subconsulta:
select * from (select id+1 as x from MyTable) as subquery order by x
En su caso, la mejor solución es probablemente usar una sub consulta:
SELECT *
FROM (
SELECT Person.Address.*
, (
SELECT TOP 1 [Name]
FROM Person.StateProvince
WHERE Person.StateProvince.StateProvinceId =
Person.Address.StateProvinceId
AND Person.StateProvince.TerritoryId IN (5, 6, 7)
ORDER BY
Person.StateProvince.TerritoryId
) AS [Name]
FROM Person.Address
) as SubqueryAlias
ORDER BY
[Name]