it-swarm.com.de

Wie wähle ich für eine Spalte und eine in einer anderen Spalte eine bestimmte aus?

Ich muss eine SQL-Datenbank abfragen, um alle unterschiedlichen Werte einer Spalte zu finden, und ich benötige einen beliebigen Wert aus einer anderen Spalte. Betrachten Sie beispielsweise die folgende Tabelle mit zwei Spalten, Schlüssel und Wert:

key     value
===     =====
one     test
one     another
one     value
two     goes
two     here
two     also
three   example

Ich möchte eine willkürlich ausgewählte Beispielzeile aus jedem einzelnen Schlüssel zurückerhalten und möglicherweise diese drei Zeilen erhalten:

key     value
===     =====
one     test
two     goes
three   example

Wie kann ich eine solche Abfrage in SQL formulieren?

32
WilliamKF

Die am einfachsten zu schreibende Abfrage ist für MySQL (mit nicht strengen ANSI-Einstellungen). Es verwendet die nicht standardmäßige Konstruktion:

SELECT key, value
FROM tableX
GROUP BY key ;

In der neuesten Version (5.7 und 8.0+), in der die strengen Einstellungen und ONLY_FULL_GROUP_BY Die Standardeinstellungen sind, können Sie die in 5.7 hinzugefügte Funktion ANY_VALUE() verwenden:

SELECT key, ANY_VALUE(value) AS value
FROM tableX
GROUP BY key ;

Für andere DBMS mit Fensterfunktionen (wie Postgres, SQL-Server, Oracle, DB2) können Sie diese wie folgt verwenden. Der Vorteil ist, dass Sie auch andere Spalten im Ergebnis auswählen können (neben key und value):

SELECT key, value
FROM tableX
    ( SELECT key, value,
             ROW_NUMBER() OVER (PARTITION BY key 
                                ORDER BY whatever)     --- ORDER BY NULL
               AS rn                                   --- for example
      FROM tableX
    ) tmp 
WHERE rn = 1 ;

Für ältere Versionen der oben genannten und für jedes andere DBMS eine allgemeine Methode, die fast überall funktioniert. Ein Nachteil ist, dass Sie mit diesem Ansatz keine anderen Spalten auswählen können. Ein weiterer Grund ist, dass Aggregatfunktionen wie MIN() und MAX() mit einigen Datentypen in einigen DBMS (wie Bit, Text, Blobs) nicht funktionieren:

SELECT key, MIN(value) AS value
FROM tableX
GROUP BY key ;

PostgreSQL verfügt über einen speziellen nicht standardmäßigen Operator DISTINCT ON, Der ebenfalls verwendet werden kann. Mit dem optionalen ORDER BY Können Sie auswählen, welche Zeile aus jeder Gruppe ausgewählt werden soll:

SELECT DISTINCT ON (key) key, value
FROM tableX
-- ORDER BY key, <some_other_expressions> ;
38
ypercubeᵀᴹ

Für MS-SQl Server :

;with FinalDataset as
(
    select *,
        row_number() over(partition by key order by value) as rownum
    from YourOriginalTable
)
select
   key,
   value
from FinalDataset 
where rownum = 1

Ebenso könnten Sie für Ihre zweite Ergebnismenge rownum = 2 haben

3
JP Chauhan

Ähnlich wie akzeptierte Antwort, aber anstelle von min () oder max () können Sie array_agg () verwenden.

SELECT key, (array_agg(value))[1] AS value
FROM tableX
GROUP BY key ;

Sie können optional Werte innerhalb des Arrays bestellen, um den größten oder kleinsten auszuwählen:

SELECT key, (array_agg(value) ORDER BY value DESC)[1] AS value
FROM tableX
GROUP BY key ;

(auf PostgreSQL überprüft)

2
alexkovelsky