sqlite2: Joining max-Werte pro Spalte aus einer anderen Tabelle (subquery reference)?
Frage
Ich verwende die folgende Datenbank:
CREATE TABLE datas (d_id INTEGER PRIMARY KEY, name_id numeric, countdata numeric);
INSERT INTO datas VALUES(1,1,20); //(NULL,1,20);
INSERT INTO datas VALUES(2,1,47); //(NULL,1,47);
INSERT INTO datas VALUES(3,2,36); //(NULL,2,36);
INSERT INTO datas VALUES(4,2,58); //(NULL,2,58);
INSERT INTO datas VALUES(5,2,87); //(NULL,2,87);
CREATE TABLE names (n_id INTEGER PRIMARY KEY, name text);
INSERT INTO names VALUES(1,'nameA'); //(NULL,'nameA');
INSERT INTO names VALUES(2,'nameB'); //(NULL,'nameB');
Was würde ich tun, ist es, alle Werte auszuwählen (Zeilen) von names
- zu dem alle Spalten von datas
werden für die Zeile angehängt werden, wo datas
.countdata
Maximum für n_id
ist (und natürlich, wo name_id = n_id
) .
Ich kann etwas dort mit der folgenden Abfrage:
sqlite> .header ON
sqlite> SELECT * FROM names AS n1
LEFT OUTER JOIN (
SELECT d_id, name_id, countdata FROM datas AS d1
WHERE d1.countdata IN (
SELECT MAX(countdata) FROM datas
WHERE name_id=1
)
) AS p1 ON n_id=name_id;
n1.n_id|n1.name|p1.d_id|p1.name_id|p1.countdata
1|nameA|2|1|47
2|nameB|||
... aber - natürlich -. Es funktioniert nur für eine einzelne Zeile (die explizit durch name_id=1
gesetzt) ??
Das Problem ist, schlägt die SQL-Abfrage, wenn ich versuche irgendwie die „aktuellen“ n_id
zu verweisen:
sqlite> SELECT * FROM names AS n1
LEFT OUTER JOIN (
SELECT d_id, name_id, countdata FROM datas AS d1
WHERE d1.countdata IN (
SELECT MAX(countdata) FROM datas
WHERE name_id=n1.n_id
)
) AS p1 ON n_id=name_id;
SQL error: no such column: n1.n_id
Gibt es eine Möglichkeit zu erreichen, was ich in SQLite2 will ??
Vielen Dank im Voraus,
Cheers!
Lösung
Oh, gut - das ist nicht trivial überhaupt war, aber hier ist eine Lösung:
sqlite> SELECT * FROM names AS n1
LEFT OUTER JOIN (
SELECT d1.*
FROM datas AS d1, (
SELECT max(countdata) as countdata,name_id
FROM datas
GROUP BY name_id
) AS ttemp
WHERE d1.name_id = ttemp.name_id AND d1.countdata = ttemp.countdata
) AS p1 ON n1.n_id=p1.name_id;
n1.n n1.name p1.d_id p1.name_id p1.countdata
---- ------------ ---------- ---------- -----------------------------------
1 nameA 2 1 47
2 nameB 5 2 87
Nun, hoffen Dies endet mit jemandem zu helfen, :) Cheers!
Notizen : Beachten Sie, dass nur anrufen max (countdata) Schrauben bis competely d_id
:
sqlite> select d_id,name_id,max(countdata) as countdata from datas group by name_id;
d_id name_id countdata
---- ------------ ----------
3 2 87
1 1 47
so richtig entsprechenden d_id
zu bekommen, müssen wir max()
auf datas
separat tun - und führen Sie dann eine Art einer Schnittstelle mit der vollen datas
(, außer dass intersect in SQLite erfordert, dass es die gleiche Anzahl von Spalten in beiden Datensätzen, was hier nicht der Fall ist - und selbst wenn wir es so gemacht, wie oben d_id
gesehen falsch sein, so schneiden wird nicht funktionieren ).
Eine Möglichkeit, das zu tun, ist in eine Art einer temporären Tabelle, und dann verwendet eine mehrere Tabellen SELECT-Abfrage, um festgelegte Bedingungen zwischen Voll datas
und der Untergruppe über max(countdata)
zurückgegeben, wie unten dargestellt:
sqlite> CREATE TABLE ttemp AS SELECT max(countdata) as countdata,name_id FROM datas GROUP BY name_id;
sqlite> SELECT d1.*, ttemp.* FROM datas AS d1, ttemp WHERE d1.name_id = ttemp.name_id AND d1.countdata = ttemp.countdata;
d1.d d1.name_id d1.countda ttemp.coun ttemp.name_id
---- ------------ ---------- ---------- -----------------------------------
2 1 47 47 1
5 2 87 87 2
sqlite> DROP TABLE ttemp;
oder können wir die neu schreiben über so eine SELECT-Unterabfrage verwendet wird, wie folgt aus (Unter wählen?):
sqlite> SELECT d1.* FROM datas AS d1, (SELECT max(countdata) as countdata,name_id FROM datas GROUP BY name_id) AS ttemp WHERE d1.name_id = ttemp.name_id AND d1.countdata = ttemp.countdata;
d1.d d1.name_id d1.countda
---- ------------ ----------
2 1 47
5 2 87