2016-04-27 6 views
1

Ich möchte die Ergebnisse der folgenden Abfrage durch eine Teilzeichenfolge der ersten 8 Zeichen der 'Versionsnummer' bestellen. Ich verstehe SUBSTRING(), also belästige mich nicht damit. Mein Problem ist es, ORDER BY in Bezug auf die UNION zu platzieren.SQL: Order By, Teilstring, Union

UPDATE: Ich brauche die Daten in der Reihenfolge der Version zurückgegeben, aber immer noch neben anderen Zeilen mit der gleichen GUID bestellt.

Die aktuelle Abfrage ist wie folgt, aber Versionen kommen in zufälliger Reihenfolge.

/**** PLAYER MATCHUPS TWO ***/  
SELECT e.[GUID], e.[KEY], e.[VALUE]  
FROM db e INNER JOIN 
    (SELECT[GUID] FROM db 
    WHERE[Key] = 'Session.Type' and[Value] = 'EndMatchTypA') g 
ON e.[GUID] = g.[GUID] 
WHERE [KEY] IN('CharacterID', 
      'OpponentID', 
      'Version') 
UNION ALL 

/**** PLAYER MATCHUPS ONE ***/ 
SELECT e.[GUID], e.[KEY], e.[VALUE] 
FROM db e INNER JOIN 
    (SELECT[GUID] FROM db 
    WHERE[Key] = 'Session.Type' and [Value] = 'EndMatchTypeB') g 
ON e.[GUID] = g.[GUID] 
WHERE[KEY] IN('CharacterID', 
     'OpponentID', 
     'Version') 

So kehren die Daten im Moment zurück.

GUID  Key    Value 
------------------------------------------- 
1313-2212 Version   3.0.4.0_x64_!# 
1313-2212 CharacterID  3 
1313-2212 OpponentID  5 
4321-1567 Version   1.0.0.0_x64_!# 
4321-1567 CharacterID  11 
4321-1567 OpponentID  2 
+0

Welche Spalte möchten Sie 'ORDER BY'? –

+0

Alle Schlüssel müssen nach dem "Wert" des Versionsschlüssels geordnet sein (z. B. 1.0.0.0> 1.2.0.0> 2.0.0.0> 3.0.0.0), aber dennoch von der GUID gebündelt werden. –

+2

IIRC Sie sollten OK sein, um das 'ORDER BY' * nach * dem letzten' WHERE' zu setzen; Er wird die beiden Anfragen der UNION anordnen. Alternativ können Sie die gesamte Abfrage in eine Unterabfrage umwandeln oder ein CTE verwenden, um dies deutlicher zu machen. Es kann jedoch schwierig für Sie sein, die gewünschte Reihenfolge basierend auf den Zeichenfolgenwerten in Ihren Daten zu erhalten. Ich tendiere dazu, dies in meinem Klienten oder in der mittleren Schicht zu tun. Die SQL-Zeichenfolgenmanipulation ist begrenzt; Sie negieren auch den Vorteil eines Index für die Versionswerte, indem Sie nach einer Funktion sortieren. – Olly

Antwort

2

Sie müssen eine andere JOIN zum db Tabelle tun, um die Version für jede [KEY] sortieren nach, dass zu bekommen:

SELECT 
    e.[GUID], e.[KEY], e.[VALUE] 
FROM db e 
INNER JOIN db g 
    ON e.[GUID] = g.[GUID] 
     AND g.[Key] = 'Session.Type' 
     AND g.[Value] IN ('EndMatchTypeA', 'EndMatchTypeB') 
INNER JOIN (
    SELECT [GUID], [KEY], [VALUE] 
    FROM db 
    WHERE 
     [KEY] = 'Version' 
)v 
    ON e.[GUID] = v.[GUID] 
WHERE 
    e.[KEY] IN ('CharacterID', 'OpponentID', 'Version') 
ORDER BY 
    SUBSTRING(v.[VALUE], 1, 8); 

Sie auch CROSS APPLY

SELECT 
    e.[GUID], e.[KEY], e.[VALUE] 
FROM db e 
INNER JOIN db g 
    ON e.[GUID] = g.[GUID] 
     AND g.[Key] = 'Session.Type' 
     AND g.[Value] IN ('EndMatchTypeA', 'EndMatchTypeB') 
CROSS APPLY (
    SELECT [GUID], [KEY], [VALUE] 
    FROM db 
    WHERE 
     [KEY] = 'Version' 
     AND [GUID] = e.[GUID] 
)v 
WHERE 
    e.[KEY] IN ('CharacterID', 'OpponentID', 'Version') 
ORDER BY 
    SUBSTRING(v.[VALUE], 1, 8); 

Credits verwenden können, um Gordon für die Beseitigung der UNION ALL.

2

Sie können die gesamte Abfrage wickeln und dann SELECT daraus ORDER BY mit:

SELECT t.[GUID], t.[KEY], t.[VALUE] 
FROM 
(
    SELECT e.[GUID], e.[KEY], e.[VALUE]  
    FROM db e INNER JOIN 
     (SELECT[GUID] FROM db 
     WHERE[Key] = 'Session.Type' and[Value] = 'EndMatchTypA') g 
    ON e.[GUID] = g.[GUID] 
    WHERE [KEY] IN('CharacterID', 
       'OpponentID', 
       'appVer') 
    UNION ALL 
    SELECT e.[GUID], e.[KEY], e.[VALUE] 
    FROM db e INNER JOIN 
     (SELECT[GUID] FROM db 
     WHERE[Key] = 'Session.Type' and [Value] = 'EndMatchTypeB') g 
    ON e.[GUID] = g.[GUID] 
    WHERE[KEY] IN('CharacterID', 
      'OpponentID', 
      'appVer') 
) t 
ORDER BY SUBSTRING(t.[VALUE], 1, 8) 

Hinweis: Getestet habe ich String Versionsnummern der Bestellung und die numerische Reihenfolge intakt zu bleiben scheint. Sie sollten sich jedoch darüber im Klaren sein, dass sich die Länge Ihrer Versionsnummer ändern könnte, was ein Problem sein könnte. Zum Beispiel, wenn Versionen zwei Ziffern werden könnten, würde dies die ORDER BY brechen, die ich gab (sowie durch die anderen Antworten gegeben).

1

Die Abfrage kann wie folgt vereinfacht werden. Verwenden Sie substring, um die ersten 8 Zeichen von value zu erhalten, und ersetzen Sie die . Zeichen durch ein leeres Zeichen, damit es als Ganzzahl geordnet werden kann.

SELECT e.[GUID], e.[KEY], e.[VALUE] 
FROM db e 
INNER JOIN 
(SELECT[GUID] FROM db 
WHERE [Key] = 'Session.Type' and [Value] = 'EndMatchTypeA') ga 
ON e.[GUID] = ga.[GUID] 
INNER JOIN 
(SELECT[GUID] FROM db 
WHERE [Key] = 'Session.Type' and [Value] = 'EndMatchTypeB') gb 
ON e.[GUID] = gb.[GUID] 
WHERE e.[KEY] IN ('CharacterID','OpponentID','appVer') 
ORDER BY cast(replace(substring(e.[VALUE],1,8),'.','') as int) 

Wenn Sie order by mit union verwenden möchten, verwenden order by am Ende der union Abfrage.

select col1,col2 from sometable --where conditions 
union all 
select col1,col2 from sometable1 --where conditions 
order by col1,col2 
1

Erstens, ich sehe nicht, warum Sie union all brauchen:

SELECT e.[GUID], e.[KEY], e.[VALUE] 
FROM db e INNER JOIN 
    db g 
    ON e.[GUID] = g.[GUID] AND 
     g.[Key] = 'Session.Type' AND 
     g.[Value] IN ('EndMatchTypeA', 'EndMatchTypeB') 
WHERE e.[KEY] IN ('CharacterID', 'OpponentID', 'Version') 
ORDER BY SUBSTRING(e.[VALUE], 1, 8); 

Dann könnte ich diese EXISTS zu einem ändern:

SELECT e.[GUID], e.[KEY], e.[VALUE] 
FROM db e 
WHERE e.[KEY] IN ('CharacterID', 'OpponentID', 'Version') AND 
     EXISTS (SELECT 1 
       FROM db g 
       WHERE e.[GUID] = g.[GUID] AND 
        g.[Key] = 'Session.Type' AND 
        g.[Value] IN ('EndMatchTypeA', 'EndMatchTypeB') 
      ) 
ORDER BY SUBSTRING(e.[VALUE], 1, 8); 

ich denke, das am besten die Absicht vermittelt der Abfrage. Und es verhindert Duplikate in g hat beide Werte. Und es macht es wahrscheinlich für den Optimierer leichter, von geeigneten Indizes Gebrauch zu machen.