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_id
1
, 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.
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
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 )
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));