Je travaille avec SQL Server 2005.
Ma requête est:
SELECT (
SELECT COUNT(1) FROM Seanslar WHERE MONTH(tarihi) = 4
GROUP BY refKlinik_id
ORDER BY refKlinik_id
) as dorduncuay
Et l'erreur:
La clause ORDER BY n'est pas valide dans les vues, fonctions en ligne, dérivées tables, sous-requêtes et expressions de table communes, sauf TOP ou FOR XML est également spécifié.
Comment utiliser ORDER BY
dans une sous-requête?
C'est l'erreur que vous obtenez (c'est moi qui souligne):
La clause ORDER BY n'est pas valide dans vues, fonctions en ligne, dérivées tables, sous-requêtes et table commune expressions, sauf si TOP ou FOR XML est également spécifié.
Alors, comment pouvez-vous éviter l'erreur? En spécifiant TOP, serait une possibilité, je suppose.
SELECT (
SELECT TOP 100 PERCENT
COUNT(1) FROM Seanslar WHERE MONTH(tarihi) = 4
GROUP BY refKlinik_id
ORDER BY refKlinik_id
) as dorduncuay
Outre le fait que order by ne semble pas avoir de sens dans votre requête .... Pour utiliser order by dans une sous-sélection, vous devez utiliser TOP 2147483647.
SELECT (
SELECT TOP 2147483647
COUNT(1) FROM Seanslar WHERE MONTH(tarihi) = 4
GROUP BY refKlinik_id
ORDER BY refKlinik_id
) as dorduncuay
Si j'ai bien compris, "TOP 100 PERCENT" ne garantit plus la commande à partir de SQL 2005:
Dans SQL Server 2005, la commande ORDER BY La clause est utilisée dans une définition de vue uniquement pour déterminer les lignes qui sont retourné par la clause TOP. L'ordre La clause BY ne garantit pas la commande résulte lorsque la vue est interrogée, sauf si ORDER BY est également spécifié dans la requête elle-même.
Voir Modifications récentes de SQL Server 2005
J'espère que ça aide, Patrick
Si vous travaillez avec SQL Server 2012 ou version ultérieure, il est désormais facile de résoudre ce problème. Ajouter un offset 0 rows
:
SELECT (
SELECT
COUNT(1) FROM Seanslar WHERE MONTH(tarihi) = 4
GROUP BY refKlinik_id
ORDER BY refKlinik_id OFFSET 0 ROWS
) as dorduncuay
Vous n'avez pas besoin de order by dans votre requête secondaire. Déplacez-le dans la requête principale et incluez la colonne que vous souhaitez classer dans la sous-requête.
cependant, votre requête ne fait que renvoyer un compte, je ne vois donc pas le point de la commande par.
Ajoutez la commande Top à votre sous-requête ...
SELECT
(
SELECT TOP 100 PERCENT
COUNT(1)
FROM
Seanslar
WHERE
MONTH(tarihi) = 4
GROUP BY
refKlinik_id
ORDER BY
refKlinik_id
) as dorduncuay
:)
Dans cet exemple, la commande n'ajoute aucune information - le COUNT d'un ensemble est le même quel que soit son ordre!
Si vous sélectionniez quelque chose qui dépendait de l'ordre, vous auriez besoin de faire l'une des choses que le message d'erreur vous indique - utilisez TOP ou FOR XML.
Une sous-requête (vue imbriquée) telle que vous l'avez renvoyée renvoie un ensemble de données que vous pouvez ensuite classer dans votre requête appelante. La commande de la sous-requête elle-même n'aura aucune incidence (fiable) sur l'ordre des résultats dans votre requête.
En ce qui concerne votre code SQL lui-même: A) Je n’ai vu aucune raison de passer commande car vous ne renvoyiez qu’une seule valeur . B) Je ne voyais aucune raison pour la sous-requête, car vous ne renvoyiez qu’une seule valeur.
J'imagine qu'il y a beaucoup plus d'informations ici que vous voudrez peut-être nous dire afin de résoudre le problème que vous avez.
peut-être que cette astuce aidera quelqu'un
SELECT
[id],
[code],
[created_at]
FROM
( SELECT
[id],
[code],
[created_at],
(ROW_NUMBER() OVER (
ORDER BY
created_at DESC)) AS Row
FROM
[Code_tbl]
WHERE
[created_at] BETWEEN '2009-11-17 00:00:01' AND '2010-11-17 23:59:59'
) Rows
WHERE
Row BETWEEN 10 AND 20;
ici la sous-requête interne ordonnée par le champ created_at (peut être n'importe laquelle de votre table)
Pour moi, cette solution fonctionne bien aussi:
SELECT tbl.a, tbl.b
FROM (SELECT TOP (select count(1) FROM yourtable) a,b FROM yourtable order by a) tbl
Si vous construisez une table temporaire, déplacez la clause ORDER BY de l'intérieur du bloc de code de la table temporaire vers l'extérieur.
Interdit:
SELECT * FROM (
SELECT A FROM Y
ORDER BY Y.A
) X;
Permis:
SELECT * FROM (
SELECT A FROM Y
) X
ORDER BY X.A;
Essayez de déplacer la clause order by en dehors de la sous-sélection et d'ajouter le champ order by dans la sous-sélection.
SELECT * FROM
(SELECT COUNT(1) ,refKlinik_id FROM Seanslar WHERE MONTH(tarihi) = 4 GROUP BY refKlinik_id)
as dorduncuay
ORDER BY refKlinik_id
Bonne journée
pour certains gars, l'ordre dans la sous-requête est discutable. la commande par en sous-requête est indispensable si vous devez supprimer des enregistrements en fonction d'un tri . like
delete from someTable Where ID in (select top(1) from sometable where condition order by insertionstamp desc)
afin que vous puissiez supprimer la dernière table de formulaire d'insertion . il y a trois façons d'effectuer cette suppression.
cependant, la commande by dans la sous-requête peut être utilisée dans de nombreux cas.
pour les méthodes de suppression qui utilisent order by dans la revue de sous-requête ci-dessous link
j'espère que ça aide. Merci à tous
Sur les besoins possibles pour commander une sous-requête est lorsque vous avez une union:
Vous générez un carnet d’appel de tous les enseignants et étudiants.
SELECT name, phone FROM teachers
UNION
SELECT name, phone FROM students
Vous souhaitez l'afficher d'abord avec tous les enseignants, suivi de tous les élèves, tous deux ordonnés par. Donc, vous ne pouvez pas appliquer un ordre global par.
Une solution consiste à inclure une clé pour forcer un premier ordre, puis à ordonner les noms:
SELECT name, phone, 1 AS orderkey FROM teachers
UNION
SELECT name, phone, 2 AS orderkey FROM students
ORDER BY orderkey, name
Je pense que son chemin est plus clair qu'un faux résultat de sous-requête compensatoire.
La clause ORDER BY n'est pas valide dans les vues, les fonctions en ligne, les tables dérivées, les sous-requêtes et les expressions de table communes, sauf si TOP ou FOR XML est également spécifié.
sélectionnez * parmi ( sélectionnez tableau.Coloumn1, CONVERT (varchar, ROW_NUMBER () OVER (ORDER BY (SELECT 1))) AS Rowno à partir de ( sélectionnez top 100 * dans Tableau1 order. par Coloumn1 desc) comme tbl) comme tbl où tbl.Rowno = 2
Pour un décompte simple comme le montre le PO, l'Ordre de n'est pas strictement nécessaire. S'ils utilisent le résultat de la sous-requête, c'est peut-être le cas. Je travaille sur un problème similaire et j'ai la même erreur dans la requête suivante:
- Je veux les lignes de la table des coûts avec une date de mise à jour égale à la date de mise à jour maximale:
SELECT * FROM #Costs Cost
INNER JOIN
(
SELECT Entityname, costtype, MAX(updatedtime) MaxUpdatedTime
FROM #HoldCosts cost
GROUP BY Entityname, costtype
ORDER BY Entityname, costtype -- *** This causes an error***
) CostsMax
ON Costs.Entityname = CostsMax.entityname
AND Costs.Costtype = CostsMax.Costtype
AND Costs.UpdatedTime = CostsMax.MaxUpdatedtime
ORDER BY Costs.Entityname, Costs.costtype
- *** Pour ce faire, il existe quelques options:
- Ajouter une clause TOP superflue, cela ressemble à un bidouillage:
SELECT * FROM #Costs Cost
INNER JOIN
(
SELECT TOP 99.999999 PERCENT Entityname, costtype, MAX(updatedtime) MaxUpdatedTime
FROM #HoldCosts cost
GROUP BY Entityname, costtype
ORDER BY Entityname, costtype
) CostsMax
ON Costs.Entityname = CostsMax.entityname
AND Costs.Costtype = CostsMax.Costtype
AND Costs.UpdatedTime = CostsMax.MaxUpdatedtime
ORDER BY Costs.Entityname, Costs.costtype
- **** Créer une table temporaire pour commander le maxCost
SELECT Entityname, costtype, MAX(updatedtime) MaxUpdatedTime
INTO #MaxCost
FROM #HoldCosts cost
GROUP BY Entityname, costtype
ORDER BY Entityname, costtype
SELECT * FROM #Costs Cost
INNER JOIN #MaxCost CostsMax
ON Costs.Entityname = CostsMax.entityname
AND Costs.Costtype = CostsMax.Costtype
AND Costs.UpdatedTime = CostsMax.MaxUpdatedtime
ORDER BY Costs.Entityname, costs.costtype
D'autres solutions de contournement possibles pourraient être les variables CTE ou de table. Mais chaque situation nécessite que vous déterminiez ce qui vous convient le mieux. J'ai tendance à regarder d'abord vers une table temporaire. Pour moi, c'est clair et simple. YMMV.