webentwicklung-frage-antwort-db.com.de

Oracle SQL GROUP BY-Hilfe "kein GROUP BY-Ausdruck"

Ich habe eine Tabelle some_table gefällt

+--------+----------+---------------------+-------+
| id     | other_id | date_value          | value |
+--------+----------+---------------------+-------+
| 1      | 1        | 2011-04-20 21:03:05 | 104   |
| 2      | 2        | 2011-04-20 21:03:04 | 229   |
| 3      | 3        | 2011-04-20 21:03:03 | 130   |
| 4      | 1        | 2011-04-20 21:02:09 | 97    |
| 5      | 2        | 2011-04-20 21:02:08 | 65    |
| 6      | 3        | 2011-04-20 21:02:07 | 101   |
| ...    | ...      | ...                 | ...   |
+--------+----------+---------------------+-------+

Und ich möchte die neuesten Datensätze für other_id1, 2 und 3. Die offensichtliche Frage, die ich mir ausgedacht habe, ist

SELECT id, other_id, MAX(date_value), value
  FROM some_table 
 WHERE other_id IN (1, 2, 3) 
 GROUP BY other_id

Es gibt jedoch eine "not a GROUP BY expression" -Ausnahme aus. Ich habe versucht, alle anderen Felder (d. H. id, value) in die GROUP BY-Klausel einzufügen, aber das gibt einfach alles zurück, genau so, als gäbe es keine GROUP BY-Klausel. (Nun, es macht auch Sinn.)

Also ... ich lese das Oracle SQL-Handbuch, und ich kann nur einige Beispiele finden, die nur Abfragen mit zwei oder drei Spalten und einige Gruppierungsfunktionen von i-have-never-seen-before umfassen. Wie gehe ich zurück und zurück?

+--------+----------+---------------------+-------+
| id     | other_id | date_value          | value |
+--------+----------+---------------------+-------+
| 1      | 1        | 2011-04-20 21:03:05 | 104   |
| 2      | 2        | 2011-04-20 21:03:04 | 229   |
| 3      | 3        | 2011-04-20 21:03:03 | 130   |
+--------+----------+---------------------+-------+

(die neuesten Einträge für jeden other_id)? Vielen Dank.

14
Yanick Rochon
 select id, other_id, date_value, value from
 (
   SELECT id, other_id, date_value, value, 
   ROW_NUMBER() OVER (partition by other_id order BY Date_Value desc) r
   FROM some_table 
   WHERE other_id IN (1, 2, 3) 
 )
 where r = 1
15

Sie können keine Spalte auswählen, die weder ein Aggregat ist noch nur aus den in der GROUP BY-Klausel verwendeten Spalten berechnet wird.

Es gibt jedoch drei Möglichkeiten, dies zu tun:

  • Sie können analytische Funktionen verwenden

    SELECT id, other_id, date_value, value
      FROM ( SELECT id, other_id, date_value, MAX(date_value) OVER (partition by other_id) max_date, value
               FROM some_table )
     WHERE max_date = date_value;
    
  • Sie können eine Selbstverknüpfung mit einer Klausel "größer als" verwenden und auf diese Weise Ihr Maximum erkennen

    SELECT t1.id, t1.other_id, t1.date_value, t1.value
      FROM some_table t1
      LEFT OUTER JOIN some_table t2
                   ON ( t1.other_id = t2.other_id AND t2.date_value > t1.date_value )
     WHERE t2.other_id IS NULL
    
  • Sie können eine Unterabfrage verwenden

      WITH max AS ( SELECT other_id, MAX(date_value) FROM some_table GROUP BY other_id )
    SELECT id, other_id, date_value, value
      FROM some_table
     WHERE ( other_id, date_value ) IN ( SELECT * FROM max )
    
8
Benoit

Wahrscheinlich ist dies der einfachste Weg

SELECT id, other_id, date_value, value
FROM some_table
WHERE date_value in (SELECT MAX(date_value)
                     from some_table
                     GROUP BY other_id
                     HAVING other_id in (1,2,3));

Testen Sie die obige Abfrage hier

0
Shivanand