2017-10-24 1 views
0

Ich habe die folgenden beiden Tabellen:Finden MAX-Wert von einer JOIN-Abfrage

Tabelle #USER

SELECT * 
INTO #USER 
FROM (
    SELECT 'A.2017.JAN' AS [KSCEN], 'John' AS [Name], 'Doe' AS [Surname] UNION ALL 
    SELECT 'A.2017.JAN' AS [KSCEN], 'Paul' AS [Name], 'Red' AS [Surname] UNION ALL 
    SELECT 'A.2017.FEB' AS [KSCEN], 'John' AS [Name], 'Doe' AS [Surname] UNION ALL 
    SELECT 'A.2017.FEB' AS [KSCEN], 'Paul' AS [Name], 'Red' AS [Surname] UNION ALL 
    SELECT 'A.2017.MAR' AS [KSCEN], 'John' AS [Name], 'Doe' AS [Surname] UNION ALL 
    SELECT 'A.2017.MAR' AS [KSCEN], 'Paul' AS [Name], 'Red' AS [Surname] UNION ALL 
    SELECT 'A.2017.MAR' AS [KSCEN], 'Kate' AS [Name], 'Blue' AS [Surname] 
) A 

Tabelle #KSCEN

SELECT * 
INTO #KSCEN 
FROM (
    SELECT 'A.2017.JAN' AS [ID], 6 AS [SEQ] UNION ALL 
    SELECT 'A.2017.FEB' AS [ID], 7 AS [SEQ] UNION ALL 
    SELECT 'A.2017.MAR' AS [ID], 8 AS [SEQ] UNION ALL 
    SELECT 'A.2017.APR' AS [ID], 9 AS [SEQ] UNION ALL 
    SELECT 'A.2017.MAY' AS [ID], 10 AS [SEQ] 
) A 

Mein Ziel ist es zu finden das Element von #KSCEN mit dem MAX SEQ, das mindestens einmal in der Tabelle #USER verwendet wird. Ich habe es mit der folgenden Unterabfrage und LEFT JOIN:

SELECT [ID] 
FROM #KSCEN 
WHERE [SEQ] = (SELECT MAX(B.[SEQ]) FROM #USER A LEFT JOIN #KSCEN B ON A.[KSCEN]=B.[ID]) 

Dies funktioniert berücksichtigen, sondern dass Tabelle #USER, in meinem Fall mehr als 30 Millionen Zeilen enthält, so dass es nicht sehr schnell ist die Abfrage als das System zu lösen müssen Sie jeder Reihe beitreten und dann den MAX finden.

Gibt es einen effizienteren Weg, um mein Problem zu lösen?

+0

Ich stimme für das Schließen dieser Frage als Off-Topic, da Optimierungsfragen in CodeReview gehören. –

+1

@ScottHunter Fragen, die mit dem Tag [query-optimization] markiert sind, sind hier sehr auf dem Vormarsch und haben eine respektable Fangemeinde von Leuten, die solche Fragen auf dieser Seite beantworten. –

Antwort

0

Ich würde vermeiden, dass correlated subquery Sie in der Where-Klausel verwendet haben. Es erzeugt einen "Reihe nach quälenden Reihe" -Effekt, wenn jede Reihe der from/where-Klausel gegen eine MAX() - Berechnung getestet wird, eine neue Abfrage für jede Reihe.

Ohne den Nutzen der realen Tabellen zu verwenden, oder Ausführungspläne, schlage ich folgendes:

with tUSER as 
(
    SELECT 'A.2017.JAN' AS [KSCEN], 'John' AS [Name], 'Doe' AS [Surname] UNION ALL 
    SELECT 'A.2017.JAN' AS [KSCEN], 'Paul' AS [Name], 'Red' AS [Surname] UNION ALL 
    SELECT 'A.2017.FEB' AS [KSCEN], 'John' AS [Name], 'Doe' AS [Surname] UNION ALL 
    SELECT 'A.2017.FEB' AS [KSCEN], 'Paul' AS [Name], 'Red' AS [Surname] UNION ALL 
    SELECT 'A.2017.MAR' AS [KSCEN], 'John' AS [Name], 'Doe' AS [Surname] UNION ALL 
    SELECT 'A.2017.MAR' AS [KSCEN], 'Paul' AS [Name], 'Red' AS [Surname] UNION ALL 
    SELECT 'A.2017.MAR' AS [KSCEN], 'Kate' AS [Name], 'Blue' AS [Surname] 
) 
, tKSCEN as (
    SELECT 'A.2017.JAN' AS [ID], 6 AS [SEQ] UNION ALL 
    SELECT 'A.2017.FEB' AS [ID], 7 AS [SEQ] UNION ALL 
    SELECT 'A.2017.MAR' AS [ID], 8 AS [SEQ] UNION ALL 
    SELECT 'A.2017.APR' AS [ID], 9 AS [SEQ] UNION ALL 
    SELECT 'A.2017.MAY' AS [ID], 10 AS [SEQ] 
) 
SELECT U.[KSCEN], MAX(K.[SEQ]) max_seq 
FROM tUSER U 
LEFT JOIN tKSCEN K ON U.[KSCEN]=K.[ID] 
GROUP BY U.[KSCEN] 
; 

Results:

Sie es bei SQL Fiddle

Abfrage 1 versuchen können,:

|  KSCEN | max_seq | 
|------------|---------| 
| A.2017.FEB |  7 | 
| A.2017.JAN |  6 | 
| A.2017.MAR |  8 | 
Verwandte Themen