Comment puis-je rejoindre la première ligne d'une sous-requête?
J'ai une table de factures et de l'enfant tableau des données connexes liées par une clé. En particulier, pour chaque facture, je suis uniquement intéressé par la première ligne de la table enfant. Étant donné que je veux, celle liée ligne pour chaque facture clés - comment puis-je y arriver?
Select i.[Invoice Number],
c.[Carrier Name]
From Invoice i
Left Join Carriers c on i.[InvoiceKey] = c.[InvoiceKey]
Where -- what?
Je suppose que sémantiquement parlant, ce que je suis à la recherche de quelque chose qui s'apparente à la notion de Top 1 c.CarrierName Group by InvoiceKey
(ou quel serait le concept de ça, si c'était possible en T-SQL.)
J'ai pensé à faire un left join sur une sous-requête, mais ça ne semble pas très efficace. Quelqu'un a une T-SQL astuces pour y parvenir?
Modifier: Désolé les gars, j'ai oublié de mentionner c'est SQL Server 2000, alors que je vais donner upvotes pour le cours de SQL Server 2005/2008 réponses qui vont travailler, je ne peux pas les accepter, j'ai peur.
- La deuxième table ont un attribut qui indique la ligne qui est premier, deuxième, etc.
- Non, autres que la séquence de l'indice
Vous devez vous connecter pour publier un commentaire.
À condition que
Carriers
a unPRIMARY KEY
appeléid
:C'est comment j'allais le faire, à l'aide d'une syntaxe légèrement différente de la vôtre (MySQL style), mais je suppose que vous pourriez l'appliquer à votre solution:
Cela va prendre tous les enregistrements de la Facture, et de le joindre avec un (ou zéro) enregistrement des Transporteurs, plus précisément le dossier qui a le même invoiceKey et seulement le premier.
Aussi longtemps que vous avez un index sur les Transporteurs.invoiceKey les performances de cette requête devrait être acceptable.
Sebastian
rn.RowNum = 1
dans le cadre de ma condition de jointure, qui devraient se joindre seulement le "premier" (tel que défini par la commande de la fenêtre de la fonction).Cela fonctionne pour moi:
ou
Dans de tels cas, j'ai souvent recours à un appareil dont j'ai ici s'appliquent à votre exemple et de décrire ci-dessous:
Je pense, c'est à peu près ce que Quassnoi a posté, seulement j'essaie d'éviter à l'aide de SELECT TOPs comme ça.
Invoice
est joint àCarriers
basé sur leur lien d'expression (InvoiceKey
dans ce cas). Maintenant,Carriers
peut avoir plusieurs lignes pour le mêmeInvoiceKey
, nous avons donc besoin de limiter la production. Et ce qui est fait à l'aide d'une table dérivée.La table dérivée des groupes de lignes de Transporteur basé sur la même expression qui est utilisé pour lier les deux tables (
InvoiceKey
).Et il y a une autre façon: au lieu de prendre la dérivée de tableau, vous pouvez utiliser
IN (subquery)
avec le même effet. C'est, à la requête complète ressemblerait alors à ceci:pour obtenir le premier transporteur pour chaque facture:
HAVING MAX(invoicenumber)
n'a même pas de l'analyser.MAX(invoicenumber)
n'est pas un prédicat.HAVING
clause.Vous pouvez également utiliser
OUTER APPLY
ainsi.Veuillez noter que l'utilisation de crochets pour inconnu noms de champ: