7
votes

Comprendre une requête SQL Server - affaire dans une clause de commande par ordre

J'essaie de jouer avec la mise en cas d'instruction code> dans l'instruction code> dans la clause code> en utilisant un distinct code> dans le SELECT Liste et trouvant un comportement étrange que je ne comprends pas. Voici quelques codes: xxx pré>

cela fonctionne. Mais si je change la 4ème ligne en lorsque "B '=" B ", BU CODE>: P>

select distinct Requester, ISO_ID as ISO, (ISO_ID - 5 + 50) AS 'someNum', BU
from LoanerHeader order by
CASE WHEN 'a' = 'b' then Requester
when 'b' = 'b' then BU
else BU   --change is here
end


2 commentaires

Quels sont les types de données de demandeur , bu et iso_id ?


@MARTINSMITH NVARCHAR, NVARCHAR, NUMERIC, respectivement. Il ne semble pas que vous aime commander par bu ou demandeur dans ce cas. Je pense que vous êtes sur quelque chose.


4 Réponses :


2
votes

Vous devez inclure l'expression complète dans la liste SELECT , pas seulement les pièces du composant.

Le comportement erratique que nous observons ici peut se produire si les types de données de demandeur , bu et iso_id sont différents. Il apparaît de l'exemple que iso_id est numérique. Je suppose que du comportement est que ni demandeur ni bu est numérique, mais ils sont tous deux des mêmes types (ou types compatibles). S'ils sont à la fois des types de caractères, il peut être nécessaire de lancer iso_id à un type de caractère dans l'affaire expression.


3 commentaires

+1 qui semble être le problème. Bien que, casting iso_id à un NvarchaRar ne le répare pas. Mais si je remplace iso_id avec une autre colonne nvarchar ( société par exemple) dans le cas de sélection et , tous les cas Travailler bien :) Curieux cependant sur pourquoi tous les cas doivent être le même type si c'est simplement spécifier une colonne à commander?


À titre de note latérale, disons que je voudrais ne pas inclure le cas dans la colonne Select car je ne le veux pas dans la sortie. Cette méthode est examinée vers le bas de cette page 4Guysfromrolla.com/wtbtech/102704-1. shtml


Je suis désolé, je pose cela, je l'ai correctement réparais :) Je devais lancer à la fois de choisir et de ne pas utiliser aucun alias.



7
votes

Les règles de cas code> sont que le résultat doit être jeté sur le type de données de la branche avec la priorité la plus élevée.

Pour la première requête Il utilise la détection de contradiction et génère simplement un plan qui trie par iso_id code> directement. Ceci est déjà numérique, donc pas besoin de couler implicitement et correspond donc à l'expression de la liste Select sans problème. P>

pour la deuxième requête, il peut encore déterminer au moment de la compilation qu'il doit commander par Bu code>. Sauf qu'il a en fait besoin de d'ordre par moulage (BU comme numérique) code> en raison de ce qui précède. Cela signifie qu'il aurait besoin de d'ordre par code> une expression calculée ne correspondant à rien dans la liste code> SELECT CODE>. D'où le problème. P>

Votre troisième requête supprime l'expression de la priorité supérieure à partir du boîtier code> supprimant ainsi la nécessité d'une mise en forme implicite (et d'où la nécessité de commander par une expression calculée) . p>

Comme l'expression calculée dépend entièrement des colonnes de la liste code> distincte de sélectionner, mais vous pouvez réécrire la deuxième requête comme suit. P>

;WITH CTE AS
(
SELECT DISTINCT Requester,
                ISO_ID              AS ISO,
                ( ISO_ID - 5 + 50 ) AS 'someNum',
                BU
FROM   LoanerHeader
)
SELECT *
FROM CTE
ORDER  BY CASE
            WHEN 'a' = 'b' THEN Requester
            WHEN 'b' = 'b' THEN BU
            ELSE ISO
          END


1 commentaires

Wow, merci pour la grande explication!



0
votes

J'ai couru quelque chose comme le tien dans SQL Server 2000 et il a échoué à chaque fois, lorsque je suis allé à SQL Server 2005, j'ai commencé à voir votre problème. J'ai changé le code pour ressembler: xxx pré>

et je reçois une erreur comme: La conversion a échoué lors de la conversion de la valeur Nvarchar "xxxxxxxxx 'en Type de données Tinyint. P>

Je ne sais pas ce que vos types de données sont, mais il semble que tous doivent être identiques et il semble que tous doivent être identiques et on dirait que Prise le type de données du champ dans la partie d'enrête comme type pour tous quand il n'est pas spécifié. P>

Quand j'ai fait quelque chose comme: p>

select Requester, ISO, someNum, BU
FROM  
(select distinct Requester, ISO_ID as ISO, (ISO_ID - 5 + 50) AS 'someNum', BU, 
CASE WHEN 'a' = 'b' then Requester
     when 'b' = 'c' then BU
     else convert(nvarchar(50), ISO_ID)
end AS SortByField
from LoanerHeader) AS dt 
order by SortByField


0 commentaires

0
votes

J'ai blogué à ce sujet il y a un moment. Il existe un exemple très simple avec le code et une explication minutieuse du problème.

SQL Server Cas / lorsque des problèmes de type de données


1 commentaires

Cool merci. Bien que je sois intéressé par pourquoi toutes les branches d'une affaire doivent être le même type. Je ne vois pas ce que le gros problème veut retourner différents types. Peut-être que je vais poser une autre question: p