J'ai le tableau suivant dans SQL Server 2008:
CREATE TABLE tbl (ID INT, dtIn DATETIME2, dtOut DATETIME2, Type INT)
INSERT tbl VALUES
(1, '05:00', '6:00', 1),
(2, '05:00', '7:00', 1),
(3, '05:01', '8:00', 1),
(4, '05:00', '8:00', 1),
(5, '05:00', '6:00', 2),
(6, '05:00', '7:00', 2)
qui sélectionne les ID de tous les enregistrements du même type, avec la même date dtIn, classés par stOut dans l'ordre croissant:
SELECT DISTINCT tbl.id FROM tbl
LEFT JOIN tbl AS t1
ON tbl.type = t1.type AND
tbl.dtIn = t1.dtIn
ORDER BY tbl.dtOut ASC
Mais cela me donne une erreur:
Les éléments ORDER BY doivent apparaître dans la liste de sélection si SELECT DISTINCT est spécifié
J'ai essayé de mettre cet ORDER BY à différents endroits et tout ne semble pas fonctionner. Qu'est-ce que je fais de mal ici?
Lorsque vous réduisez les identifiants individuels, vous créez la possibilité que chaque identifiant puisse avoir plus d'un dtOut associé. Lorsque cela se produit, comment Sql Server saura-t-il quel ordre utiliser?
Tu pourrais essayer:
SELECT t1.id
FROM tbl t1
LEFT JOIN tbl t2 on t1.type = t2.type AND t1.dtIn = t2.dtIn
GROUP BY t1.id, t2.dtOut
ORDER BY t2.dtOut
Cependant, comme je l'ai mentionné ci-dessus, cela peut ouvrir la possibilité d'avoir le même identifiant répertorié plus d'une fois, s'il correspond à plus d'un enregistrement sur la table de droite.
Cela n'a pas de sens de COMMANDER par une colonne qui n'est pas incluse dans la liste des éléments DISTINCT.
Utilisons un scénario simple. Tout d'abord, une table FruitPerson
:
Fruit PersonName
----- ------
Apple Joe
Apple Mary
Peach Karen
Peach Lance
Voici la requête équivalente à ce que vous essayez de faire:
SELECT DISTINCT Fruit
FROM FruitPerson
ORDER BY PersonName;
Le résultat de cette requête sans le ORDER BY
est-ce:
Fruit
-----
Apple
Peach
Mais maintenant, la question est: comment le moteur doit-il ordonner ces deux valeurs "Apple" et "Peach" par PersonName
? Lequel PersonNames? Il y a deux personnes par fruit! Quel (s) nom (s), exactement, doit-il utiliser pour décider si Apple
ou Peach
vient en premier?
Au lieu de cela, réécrivez votre requête sous forme d'agrégat:
SELECT Fruit, MinName = Min(PersonName) -- which name to order on
FROM FruitPerson
GROUP BY Fruit -- here's how you get your distinctness
ORDER BY MinName;
Vous rencontriez cette erreur car vous n'avez pas mis (tbl.dtOut) dans la liste de sélection.
SELECT DISTINCT tbl.dtOut FROM tbl
LEFT JOIN tbl AS t1
ON tbl.type = t1.type AND
tbl.dtIn = t1.dtIn
ORDER BY tbl.dtOut ASC
Vous obtiendrez un ensemble de résultats (ayant 3 lignes) et si vous voulez aussi le champ id alors
SELECT DISTINCT tbl.dtOut, tbl.ID FROM tbl
LEFT JOIN tbl AS t1
ON tbl.type = t1.type AND
tbl.dtIn = t1.dtIn
ORDER BY tbl.dtOut ASC
(ayant 6 lignes, car il donne la combinaison distincte hors champ id/date)
Vous ne pouvez utiliser que les colonnes de la clause ORDER BY qui font partie de votre instruction select lorsque vous utilisez la clé "DISTINCT" Word. Vous ne pouvez donc commander que par tbl.id
Si les identifiants sont uniques, le mot clé DISTINCT n'a aucun sens et entraînera une dégradation des performances et vous pouvez simplement le supprimer. Dans le cas où ils ne le sont pas et que vous décidez de sélectionner également tbl.dtOut tout en conservant DISTINCT, la paire tbl.id et tbl.dtOut peut vous donner plusieurs entrées ayant le même tbl.id, ce qui n'est probablement pas souhaité.
Vérifiez cet article pour les solutions de contournement possibles et l'explication des raisons pour lesquelles de telles requêtes sont interdites.
Vous devez inclure la colonne tbl.dtOut dans votre liste de sélection afin qu'elle sache sur quoi commander.
SELECT DISTINCT tbl.id, tbl.dtOut FROM tbl
LEFT JOIN tbl AS t1
ON tbl.type = t1.type AND
tbl.dtIn = t1.dtIn
ORDER BY tbl.dtOut ASC