I've got a table of invoices and a child table of related data related by key. In particular, for each invoice, I'm interested in only the first related row from the child table. Given that I want the one related row for every invoice key - how do I accomplish this?
Select i.[Invoice Number],
c.[Carrier Name]
From Invoice i
Left Join Carriers c on i.[InvoiceKey] = c.[InvoiceKey]
Where -- what?
I guess semantically speaking, what I'm looking for something akin to the concept of Top 1 c.CarrierName Group by InvoiceKey
(or what would be the concept of that if that were possible in T-SQL.)
I've thought about doing a left join on a subquery, but that doesn't seem very efficient. Does anyone have any T-SQL tricks to achieve this efficiently?
Edit: Sorry guys, I forgot to mention this is SQL Server 2000, so while I'm going to give upvotes for the current SQL Server 2005/2008 responses that will work, I can't accept them I'm afraid.
In such cases I often employ a device which I here apply to your example and describe below:
I think, this is roughly what Quassnoi has posted, only I try to avoid using SELECT TOPs like that.
Invoice
is joined withCarriers
based on their linking expression (InvoiceKey
in this case). Now,Carriers
can have multiple rows for the sameInvoiceKey
, so we need to limit the output. And that is done using a derived table.The derived table groups rows from Carrier based on the same expression that is used for linking the two tables (
InvoiceKey
).And there's another way: instead of joining the derived table you could use
IN (subquery)
with the same effect. That is, the complete query would then look like this:This is how I would do it, using a slightly different syntax than yours (MySQL style), but I guess you could apply it to your solution as well:
This will take all records from Invoice, and join it with one (or zero) record from Carriers, specifically the record which has the same invoiceKey and only the first one.
As long as you have an index on Carriers.invoiceKey the performance of this query should be acceptable.
Sebastian
Provided that
Carriers
has aPRIMARY KEY
calledid
:to get the first carrier for each invoice:
This works for me:
or