2016-07-14 4 views
1

Ich suche nach Optionen, wie Sie den ersten Datensatz pro Gruppe in SQLite, wo die Sortierung der Gruppe über einen zusammengesetzten Schlüssel ist.SQLite - Erste pro Gruppe - Composite Order & entgegengesetzte Sortierung

Beispiel Tabelle:

Key_1 | Sort1 | Sort2 | Val_1 | Val_2 
-------+-------+-------+-------+------- 
    1 | 1 | 3 | 0 | 2 
    1 | 1 | 2 | 2 | 4 
    1 | 1 | 1 | 4 | 6 
    1 | 2 | 2 | 6 | 8 
    1 | 2 | 1 | 8 | 1 
    2 | 1 | 2 | 0 | 5 
    2 | 1 | 1 | 1 | 6 
    2 | 2 | 3 | 2 | 7 
    2 | 2 | 2 | 3 | 8 
    2 | 2 | 1 | 4 | 9 

Ziel:
- Sortieren von Daten von Key_1 ASC, Sort1 ASC, Sort2 DESC
- Wählen ersten Datensatz pro eindeutiger Key_1

Key_1 | Sort1 | Sort2 | Val_1 | Val_2 
-------+-------+-------+-------+------- 
    1 | 1 | 3 | 0 | 2 
    2 | 1 | 2 | 0 | 5 

analytische Funktion Lösung ...

SELECT 
    * 
FROM 
(
    SELECT 
     *, 
     ROW_NUMBER() OVER (PARTITION BY Key_1 
           ORDER BY Sort1, 
             Sort2 DESC 
         ) 
           AS group_ordinal 
    FROM 
     table 
) 
    sorted 
WHERE 
    group_ordinal = 1 

Aufwendige ANSI-92 Ansatz ...

SELECT 
    table.* 
FROM 
    table 
INNER JOIN 
(
    SELECT 
     table.Key1, table.Sort1, MAX(table.Sort2) AS Sort2 
    FROM 
     table 
    INNER JOIN 
    (
     SELECT 
      Key_1, MIN(Sort1) 
     FROM 
      table 
     GROUP BY 
      Key_1 
    ) 
     first_Sort1 
      ON table.Key_1 = first_Sort1.Key_1 
      AND table.Sort1 = first_Sort1.Sort1 
    GROUP BY 
     table.Key1, table.Sort1 
) 
    first_Sort1_last_Sort2 
     ON table.Key_1 = first_Sort1_last_Sort2.Key_1 
     AND table.Sort1 = first_Sort1_last_Sort2.Sort1 
     AND table.Sort2 = first_Sort1_last_Sort2.Sort2 

Dies erfordert eine Menge Verschachtelung und selbst verbindet. Das ist umständlich genug, wenn es nur zwei Sortierspalten gibt.

Mein aktuelles Beispiel hat sechs Sortierspalten.

Ich möchte auch so etwas wie die folgenden vermeiden, da es nicht(meines Wissens) garantiert/deterministisch ist ...

SELECT 
    table.* 
FROM 
    table 
GROUP BY 
    table.Key_1 
ORDER BY 
    MIN(table.Sort1), 
    MAX(table.Sort2) 

es andere Optionen, die ich sehe ich gerade nicht?

Antwort

1

Ich glaube, dies in SQLite arbeiten:

select t.* 
from table t 
where exists (select 1 
       from (select t2.* 
        from table t2 
        where t2.id = t.id 
        order by t2.sort1 asc, t2.sort2 desc 
        limit 1 
        ) t2 
       where t2.sort1 = t.sort1 and t2.sort2 = t.sort2 
      ); 

Meine Sorge ist, ob SQLite korrelierten Referenzen in verschachtelten Unterabfragen ermöglicht. Wenn nicht, können Sie einfach = verwenden und die Werte verketten zusammen:

select t.* 
from table t 
where (sort1 || ':' || sort2) = 
      (select (sort1 || ':' || sort2) 
      from table t2 
      where t2.id = t.id 
      order by sort1 asc, sort2 desc 
      limit 1 
     ); 
+0

Nizza, beide Abfragen geben WHERE (a, b) = (SELECT a, b FROM x) ', aber SQLite kompatibel ist. Ich gebe ihnen beide einen Versuch, dann belasten Sie mein Gehirn, welche Option am wenigsten verschleiert ist * (für jeden armen Entwickler, der damit zu tun hat, ist ein Jahr Zeit) *. – MatBailie

+0

@MatBailie. . . Obwohl ich von der zweiten Lösung nicht begeistert bin, ist sie für jemanden, der die Anfrage zum ersten Mal liest, wahrscheinlich klarer. –

+0

ging mit dem ersten, um Probleme mit impliziten Typkonvertierungen zu vermeiden. Dann fügte man verständliche Kommentare über die Korrelation und die Reihenfolge hinzu, indem man Partitionen ähnlich war und in analytischen Funktionen ordnete. Habe eine interessante Einschränkung finanziert. Die Felder der äußeren Abfrage können in der WHERE-Klausel, nicht jedoch in ORDER BY referenziert werden. Nicht sicher, ob das eine nicht unterstützte Funktionalität ist. Wird noch einen Tag tiefer graben. – MatBailie