2016-12-29 1 views
2

Angenommen, ich habe diese 3 Tabellen:SQL Server: Wählen Sie nur letzte Datensatz pro Kunde aus einer Join-Abfrage

Customer type 1

Customer type 2

enter image description here

Die ersten zwei Tabellen definieren Kunden verschiedener Typen, dh zweite Tabelle hat andere Spalten, die nicht in Tabelle 1 enthalten sind. Ich habe sie einfach gleich gelassen, um die Komplexität zu sparen.

Die dritte Tabelle definiert Bestellungen für beide Arten von Kunden. Jeder Kunde hat mehr als einen Auftrag

Ich mag die letzte Bestellung für jeden Kunden wählen, dh die Reihenfolge mit order_id 4 für customer 1, die auf 23/12/2016 und die Reihenfolge mit order_id 5 für customer 2 erstellt wurden, das erstellt wurde am 26/12/2016

habe ich versucht, so etwas wie diese:

select * 
from customertype1 
left join order on order.customer_id = customertype1.customer_id 
order by order_id desc; 

Aber das gibt mir mehrere Datensätze für jeden Kunden, wie ich gesagt habe ich oben für jeden customertype1 nur den letzten Auftrag wünsche.

+0

können Sie CROSS APPLY und SELECT TOP 1 ... ORDER BY DateCreated DESC innerhalb der CROSS APPLY-Abfrage verwenden – Cato

Antwort

3

Wenn Sie den letzten Auftrag für jeden Kunden wollen, dann müssen Sie nur die orders Tabelle:

select o.* 
from (select o.*, 
      row_number() over (partition by customer_id order by datecreated desc) as seqnum 
     from orders o 
    ) o 
where seqnum = 1; 

Wenn Sie alle Kunden aufnehmen möchten, dann müssen Sie die beiden Tabellen kombinieren. Unter der Annahme, sie sich gegenseitig aus:

with c as (
     select customer_id from customers1 union all 
     select customer_id from customers2 
    ) 
select o.* 
from c left join 
    (select o.*, 
      row_number() over (partition by customer_id order by datecreated desc) as seqnum 
     from orders o 
    ) o 
    on c.customer_id = o.customer_id and seqnum = 1; 

Eine Notiz über Ihre Datenstruktur: Sie sollten für alle Kunden einen Tisch. Sie können dann eine Fremdschlüsseleinschränkung zwischen orders und customers definieren. Für die zusätzlichen Spalten können Sie zusätzliche Tabellen für die verschiedenen Kundentypen anlegen.

0

Verwenden Sie ROW_NUMBER() und PARTITION BY.

  • ROW_NUMBER(): es wird Sequenz geben nicht auf Ihre jede Zeile
  • PARTITION BY: es wird gruppieren Sie Ihre Daten durch bestimmte Spalte

Wenn Sie ROW_NUMBER() und PARTITION BY beide zusammen dann die erste Partition Gruppe Ihre records und dann row_number geben dann die Sequenz no für jede Gruppe an, also für jede Gruppe hast du die Startsequenz von 1

Hilfe Link: Example of ROW_NUMBER() and PARTITION BY

0

Dies ist die allgemeine Idee. Sie können die Details ausarbeiten.

with customers as 
(select customer_id, customer_name 
from table1 
union 
select customer_id, customer_name 
from table2) 

, lastOrder as 
(select customer_id, max(order_id) maxOrderId 
from orders 
group by customer_id) 

select * 
from lastOrder join customers on lastOrder.Customer_id = customers.customer_id 
join orders on order_id = maxOrderId