2010-11-03 18 views
0

Il s'agit d'une version simplifiée d'une requête réelle pour montrer le problème. Il peut être exécuté sur la base de données exemple AdventureWorks:MS SQL 2005 - ordre par assemblage avec échec de la sous-requête

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] 

Cela fonctionne bien, mais mon problème est que si j'ajoute la collation à l'ordre par le champ, je reçois un message d'erreur étrange:

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 

et l'erreur est:

Msg 207, Level 16, State 1, Line 7 
Invalid column name 'Name'. 

la requête avec la clause COLLATE fonctionne bien s'il n'y a pas sous-requête, mais je besoin d'être comme ça (pour une raison compliquée, mais s'il vous plaît, croyez-moi :)).

Est-ce que quelqu'un sait pourquoi cette requête échoue, et ce qui peut être une solution de contournement possible? Est-ce un bug?

Merci! SQL

+0

Inte Au repos, je ne dispose pas d'AdventureWorks pour le moment, mais j'ai juste essayé une requête similaire sur une base de données différente mais je n'ai pas pu répliquer votre problème. – pavanred

+0

Salut! Vous pouvez télécharger la db AdventureWorks sur http://msftdbprodsamples.codeplex.com/releases/view/4004 –

Répondre

2

SQL Server ne vous permet pas de faire référence aux colonnes par alias dans la clause order by. Par exemple, cela ne fonctionnera pas:

select id+1 as x from MyTable order by x 

Mais vous pouvez corriger cela en répétant la définition de la colonne:

select id+1 as x from MyTable order by id+1 

Ou en utilisant un sous-requête:

select * from (select id+1 as x from MyTable) as subquery order by x 

Dans votre cas , la meilleure solution est probablement d'utiliser une sous-requête:

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] 
+0

Merci pour votre réponse rapide, maintenant je comprends pourquoi cela fonctionne (ou ne fonctionne pas). Une autre excellente explication ici: http://social.technet.microsoft.com/Forums/en/transactsql/thread/9d948214-9bae-4df0-870d-507e43407af9 –