2010-12-02 6 views
5

Je ne comprends pas pourquoi cela ne fonctionne pas:SQL Ordre personnalisé par

select distinct a.QuestionID,a.QuestionName,b.AnswerID,b.AnswerName 
    from @TempExportList a 
    join tblAnswers b 
    on a.QuestionID = b.QuestionID 
    where [email protected] 
    order by (case when a.QuestionName='A' then 0 
        when a.QuestionName='B' then 1 
        else a.QuestionID 
       end) 

Je reçois l'erreur suivante -

éléments ORDER BY doit apparaître dans la liste de sélection si SELECT DISTINCT est spécifié.

Mais cela fonctionne très bien:

select distinct a.QuestionID,a.QuestionName,b.AnswerID,b.AnswerName 
    from @TempExportList a 
    join tblAnswers b 
    on a.QuestionID = b.QuestionID 
    where [email protected] 
    order by a.QuestionID 

Répondre

8

Le message d'erreur explique parfaitement le problème.

Dans le premier exemple l'élément ORDER BY - CASE WHEN ... END - ne figure pas dans la liste SELECT.

Dans le deuxième exemple, l'élément ORDER BY - a.QuestionID - apparaît dans la liste SELECT.

Pour fixer le premier exemple, vous aurez besoin de faire quelque chose comme ceci:

SELECT DISTINCT a.QuestionID, a.QuestionName, b.AnswerID, b.AnswerName, 
       CASE WHEN a.QuestionName = 'A' THEN 0 
        WHEN a.QuestionName = 'B' THEN 1 
        ELSE a.QuestionID 
       END 
FROM @TempExportList AS a 
    JOIN tblAnswers AS b 
     ON a.QuestionID = b.QuestionID 
WHERE a.PaperID = @PaperID 
ORDER BY CASE WHEN a.QuestionName = 'A' THEN 0 
       WHEN a.QuestionName = 'B' THEN 1 
       ELSE a.QuestionID 
     END 
+0

Merci. J'aurais pensé qu'il se référait à un.QuestionName et un.QuestionID n'étant pas dans le select, avec 0,1 ... n étant juste un numéro de commande et pas nécessaire dans le cadre de la sélection. – Bob

+0

Merci. L'erreur est claire mais je pensais que seules les colonnes devaient être ajoutées. Pour moi, SQL peut être assez simple et très confus en même temps -_- – ErTR

2

J'aurais pensé que le message d'auto explanitory.

Vous avez sélectionné un identificateur distinct sur a.QuestionID, un .QuestionName, b.AnswerID et b.AnswerName. Par conséquent, il peut y avoir des lignes de données avec les mêmes valeurs respectives pour chacun de ces champs, mais une autre pour votre instruction case.

Considérez cette

a.QuestionID a.QuestionName b.AnswerID b.AnswerName [case statement] 

1    'One'   2   'Two'   0 
1    'One'   2   'Two'   1 

Comment la requête savoir quelle valeur dans la dernière colonne à utiliser dans l'ordre? Est-ce que c'est 0? C'est 1? Tout simplement, il ne peut pas déterminer, donc il ne peut pas l'utiliser, d'où l'erreur.

Le deuxième exemple est correct, car un.QuestionID apparaît dans la liste SELECT et la requête peut heureusement appliquer l'ordre.

+1

Ceci est un peu un argument faux IMO. Il ** pourrait ** déterminer que seules les fonctions déterministes étaient utilisées et que l'expression de cas dans l'ordre par les colonnes seulement utilisées dans la liste de sélection. SQL Server 2000 vous permet de faire cela. AFAIK c'était un changement de rupture dans SQL Server 2005 afin de répondre à la norme ANSI. –

4

Vous pouvez contourner ce avec un CTE

;WITH T AS 
(
SELECT DISTINCT a.QuestionID,a.QuestionName,b.AnswerID,b.AnswerName 
    FROM @TempExportList a 
    JOIN tblAnswers b 
    ON a.QuestionID = b.QuestionID 
    WHERE [email protected] 
) 
SELECT * 
FROM  T 
ORDER BY 
     CASE 
        WHEN QuestionName='A' 
        THEN 0 
        WHEN QuestionName='B' 
        THEN 1 
        ELSE QuestionID 
     END