“La sous-requête a retourné plus de 1 valeur” pour la sous-requête SELECT
Je suis à l'aide de MS SQL Server Management Studio 2008. Je vais avoir un problème avec l'écriture d'une sous-requête. C'est l'ensemble de la requête comme suit:
SELECT DISTINCT
FH.ShipDate, AVG(FH.[Dist Freight]) AS [Atlantic Freight Charge],
(SELECT DISTINCT [Non-Atlantic Freight Charge]
FROM
(SELECT DISTINCT
FH.ShipDate, AVG(FH.[Dist Freight]) AS [Non-Atlantic Freight Charge]
FROM dbo.vw_FreightHistory AS FH
WHERE VendorName != 'Atlantic Trucking'
GROUP BY ShipDate, VendorName) AS [Non-Atlantic Freight Charge])
FROM dbo.vw_FreightHistory as FH
WHERE VendorName = 'Atlantic Trucking'
GROUP BY ShipDate, VendorName
ORDER BY ShipDate
Le problème est venu quand j'ai ajouté que la deuxième sous-requête. La première sous-requête ne retourne pas d'erreurs mais elle a montré que la totalité de la somme moyenne des "Dist Fret" dans chaque ShipDate, plutôt que la moyenne que pour la ShipDate. J'ai écrit le deuxième sous-requête pour essayer de résoudre ça, mais maintenant j'ai cette erreur:
Msg 512, Niveau 16, État 1, Ligne 1
La sous-requête a retourné plus de valeur 1. Ce n'est pas permis lorsque la sous-requête suit =, !=, <, <= , >, >= ou lorsque la sous-requête est utilisée comme une expression.
S'il vous plaît laissez-moi savoir si je me dois de préciser quoi que ce soit.
Pas lié à votre message d'erreur, mais vous avez l'air d'être en manque une parenthèse fermante.
les crochets sont beaux, rien ne manque
[Non-Atlantique Frais de transport] retourner plusieurs résultats. Vous avez construit moyenne par jour, donc si vous extraire de la moyenne pour aujourd'hui et pour demain, votre DISTINCT [Non-Atlantique Frais de transport] renvoie 2 résultat.
c'est une très grande table, mais les attributs que je suis en train d'utiliser sont ShipDate, Nomfournisseur, et Dist Fret. Fondamentalement, ce que je suis en train de faire, c'est montrer une tendance de la moyenne "Dist Fret" coût pour un VendorName et ensuite la moyenne pour tous les autres vendeurs dans une autre colonne. La sortie doit être en trois colonnes: chaque ShipDate, la moyenne des coûts de transport pour le Vendeur à cette date, et la moyenne des coûts de transport pour tous les autres vendeurs.
OriginalL'auteur Martin | 2013-07-19
Vous devez vous connecter pour publier un commentaire.
Je pense que ce que vous voulez, c'est quelque chose comme ceci:
Cela semble fonctionner à merveille. Je ne savais pas qu'on pouvait les cas d'utilisation dans SQL (je suis un gros utilisateur de base), c'est vraiment bien. Regarde comme il va à travers et s'empare de la moyenne Dist Fret si le nom de l'Atlantique du Camionnage, et si ce n'est pas dans le dossier du jour, puis elle retourne Null. Puis il fait de même pour tous les autres transporteurs. Merci beaucoup!! En passant, avez-vous des recommandations pour les sites web qui enseignent ces plus nuancée des requêtes?
Cet exemple particulier de vint ans de la rédaction de rapports financiers et de regarder le code. Pour plus de sql avancé des concepts et des requêtes j'aime cette ressource ici, bien qu'il ne peut pas nécessairement s'appliquer dans votre cas: sommarskog.se
Ah, eh bien encore une fois j'apprécie l'entrée. Je vais vérifier que le site web.
Ah, content de voir que quelqu'un a eu la même réponse que j'ai est venu, et un peu plus sèchement. Martin, j'espère que ma réponse au moins sert une explication sur les raisons de votre requête eu des problèmes.
OriginalL'auteur Petio Ivanov
Le problème est que vous avez une sous-requête renvoyant plusieurs lignes et que vous essayez de stocker une valeur dans une seule rangée/colonne combinaison.
De comprendre pourquoi c'est le cas, nous allons regarder ce que le résultat pourrait ressembler à l'extérieur pour la requête, de l'Atlantique Frais de transport':
Tableau 1 - Atlantique Frais De Transport
Et regardons ce que l'intérieur de la sous-requête peut renvoyer:
Tableau 2 - Non-Atlantique Frais De Transport
Enfin, ce qui ne l'distinctes
Non-Atlantic Freight Charge
lignes ressemblent pour le tableau 2?Tableau 3 - Distinctes Non-Atlantique Frais De Transport
Maintenant, en SQL, vous spécifiez que vous voulez un rapport avec trois colonnes, basé sur votre clause SELECT. Voici comment qui dispose:
Vous voir la première colonne est
ShipDate
, la deuxième colonne estAtlantic Freight Charge
, et la troisième colonne est une requête de chaque distinctesNon-Atlantic Freight Charge
à partir d'un noyau sous-requête.Pour SQL Server pour représenter correctement, imaginez que vous essayez de mettre les résultats de cette requête dans le premier tableau.
Donc, pour la première ligne du Tableau 1:
Nous avons besoin d'ajouter une colonne
Non-Atlantic Freight Charge
, et nous avons besoin de stocker les résultats de la requête dans le Tableau 3:Uh oh. Nous avons une table, à l'intérieur de notre table.
C'est ça le problème, nous avons un tableau dans un autre tableau!
Il y a donc deux solutions à votre problème. Vous devez évaluer la performance de chacun.
La première est d'utiliser une fonction appelée Les Expressions de Table communes ou d'expressions de table communes pour exécuter deux requêtes distinctes et joindre les résultats.
Que la requête devrait ressembler à ceci:
CTE Solution
Il y a quelques changements que j'ai faits qui, je dois le souligner:
ORDER BY
est effectivement interdit dans les expressions de table communes de toute façon si je dois déplacer cet alinéa à la fin.FULL OUTER JOIN
pour relier entre eux, de sorte que toute la ligne qui manquent dans l'un apparaît toujours, mais il va apparaître avec un zéro. Assurez-vous que c'est ce que vous voulez.COALESCE
pour s'assurer que dans le cas où il y a un jour sansAtlantic Freight Charge
s et donc il n'y a pas de ShipDate correspondant à ce jour dans leAtlantic
CTE, alors il utilisera la date de laNonAtlantic
CTE.La façon dont cela fonctionne est qu'il relie les deux requêtes comme ceci:
Et donc la
COALESCE
etISNULL
permettez-moi de tourner que dans un seul ensemble de données comme ceci:Cependant que, probablement, n'est-ce pas la solution la plus performante
La plus facile à mettre en œuvre, prenez vos deux requêtes, exécuter les deux d'entre eux, et joindre les résultats. Mais SQL Server prend en charge les fonctions d'agrégation qui vous permettent de partition les résultats. Vous pouvez être intéressé par la recherche dans la sémantique de la Au COURS de la Clause pour en savoir plus sur comment vous pouvez exécuter votre rapport en une seule requête. J'ai mis en place des requêtes comme moi-même, mais généralement à l'aide d'
SUM
s, pasAVG
s. Je voudrais offrir une possible mise en œuvre d'une solution contenant le PLUS de la clause, mais il pourrait être un peu plus compliqué et je serais inquiet que j'avais loupé en moyenne les résultats correctement. En fait, maintenant que j'y pense, quelque chose comme cela peut bien fonctionner:Mais j'ai oublié si AVG compte des lignes de valeur null ou pas.
De toute façon, j'espère que j'ai à la fois répondu à votre question et vous a aidé à comprendre pourquoi votre requête avait un problème.
Bien fichu, je ne m'attendais pas a une réponse détaillée comme la vôtre. Merci pour le décomposant pièce par pièce et me montrant exactement pourquoi elle n'avait pas de travail, ainsi que l'offre de ces deux solutions. J'ai fini par aller avec le cas que Petio soumis. Je n'étais pas au courant de la "FUSIONNER" la clause, c'est vraiment chouette et utile. Beaucoup apprécié!
Merci, Martin! Alors que je déteste vendre ma pudeur pour la réputation sur le site, ce serait apprécié si vous pouviez donner ma solution un upvote/plus d'un, ce qu'ils appellent juste pour indiquer que vous avez trouvé utile. Petio la solution plus que suffit à vos besoins et j'espère que d'autres personnes qui trouvent ce post trouver à la fois sa réponse et la mienne utile.
Malheureusement je n'ai pas assez de rep pour upvote vous, mais je vais certainement revenir à ce post quand je peux. Merci encore.
Oh, ne savais même pas que vous aviez besoin de réputation pour upvote. Eh bien, j'espère que vous apprécierez la StackOverflow de la communauté. 🙂
OriginalL'auteur Aaron Friel
Cela dépend de ce que vous vous attendez à apparaître dans la colonne unique si plus d'une ligne est renvoyée?
Si vous voulez le total de charges, utilisation
SUM()
autour de votre multi-ligne-de retour à la sous-requête:OriginalL'auteur Bohemian