SQL: Kann man diese Anfrage simpler gestalten
*jiriki*
- datenbank
Hi,
ich hab eine Tabelle 'discs' mit den Attributen 'id' (Primary Key), 'title' und 'ripped' auf einem PostgreSQL-Server. Ripped gibt mir an, ob ich das Album selbst gerippt hab, oder nicht. Das heisst, es kann mehrere Einträge des gleichen Albums geben (mal selbst gerippt, mal nicht, und das ganze öfters).
Jetzt möchte ich jedes Album nur einmal ausgegeben haben, wobei es mir, falls es mehrere Einträge für ein Album gibt, immer das/eines der selbstgerippten Versionen ausspucken soll.
Bisher läuft das bei mir so:
CREATE TEMPORARY TABLE result
SELECT *
FROM discs
ORDER BY ripped DESC;
ALTER IGNORE TABLE blubb
ADD PRIMARY KEY ( name );
SELECT * FROM result;
Kann man das ganze auch ergonomisch in einem SELECT-Befehl schachteln?
Grüßle, *jiriki*
Hallo,
warum nicht :
SELECT * FROM discs ORDER BY ripped DESC limit 1; ??
warum nicht :
SELECT * FROM discs ORDER BY ripped DESC limit 1; ??
Ganz so einfach gehts leider nicht. Damit würdest du deine Ausgabemenge auf insg. 1 Datensatz reduzieren. Ich will aber ja zu jedem Album einen Datensatz.
yo,
welches DBMS benutzt du und welche Version ?
Ilja
welches DBMS benutzt du und welche Version ?
Ähm, DBMS ist wie gesagt PostgreSQL (oder verwechsel ich da was?) und Version ist 8.1x.
yo,
Ähm, DBMS ist wie gesagt PostgreSQL (oder verwechsel ich da was?) und Version ist 8.1x.
wer lesen kann, ist klar im vorteil, da habe ich wohl was übersehen. ;-)
was deine abfrage angeht:
SELECT tab1.id, tab1.title, tab1.ripped
FROM discs AS tab1
WHERE tab1.id IN
(
SELECT MAX(tab2.id)
FROM discs AS tab2
WHERE tab2.ripped = "selbt gerippt"
GROUP BY tab2.title
)
das gibt dir erst einmal einen datensatz pro titel der gerippt wurde. nun musst du das ganze nur noch mit UNION verbinden, bei den titel, die keine gerippte version haben. aber ich weiß nicht, nach welchen kriterien du da eine auswahl treffen willst.
Ilja
SELECT tab1.id, tab1.title, tab1.ripped
FROM discs AS tab1
WHERE tab1.id IN
(
SELECT MAX(tab2.id)
FROM discs AS tab2
WHERE tab2.ripped = "selbt gerippt"
GROUP BY tab2.title
)das gibt dir erst einmal einen datensatz pro titel der gerippt wurde. nun musst du das ganze nur noch mit UNION verbinden, bei den titel, die keine gerippte version haben. aber ich weiß nicht, nach welchen kriterien du da eine auswahl treffen willst.
Mh, dann dürfte ich im zweiten SELECT nur noch die Datensatz-Gruppierungen betrachten, in denen _alle_ Datensätze den Wert "nicht selbst gerippt" in "ripped" haben. Gibt es so eine Klausel im Sinne von
GROUP BY x
HAVING ALL y = "not self ripped"
?
Greets, *jiriki*
yo,
Mh, dann dürfte ich im zweiten SELECT nur noch die Datensatz-Gruppierungen betrachten, in denen _alle_ Datensätze den Wert "nicht selbst gerippt" in "ripped" haben.
dafür musst du halt zwei bedingungen beachten. zum einen musst du nur die datensätze einschließen, die kein selbst gerippt im jeweiligen Titel haben. und dann musst du dich für einen ripped wert entscheiden. ich weiß aber nicht welchen du willst und so nehmen ich einfach einen mit MAX().
SELECT tab1.id, tab1.title, tab1.ripped
FROM discs AS tab1
WHERE tab1.id IN
(
SELECT MAX(tab2.id)
FROM discs AS tab2
GROUP BY tab2.titel
)
AND 0 =
(
SELECT COUNT(*)
FROM discs AS tab3
WHERE tab3.ripped = "self ripped"
AND tab3.titel = tab1.titel
)
eine andere möglichkeit wären Operatoren der Mengenlehre wie INTERCEPT oder andere. aber ich weiß nicht, ob dein dbms so etwas unterstützt.
Ilja
eine andere möglichkeit wären Operatoren der Mengenlehre wie INTERCEPT oder andere. aber ich weiß nicht, ob dein dbms so etwas unterstützt.
Mal angenommen, es unterstützt diese Operatoren. Gäbe es dann eine etwas schlankere Anfrage als die bisher erarbeitete? Mir gefällt die Lösung mit der Temporary Table bisher besser, weil sie codemäßig kürzer ist (auch wenn ich nicht weiss, wie sich das speicherplatzmäßig auswirkt (TemporaryTable <-> Nur Select-Anfrage)).
Also an einer Mengenoperatorenlösung wäre ich durchaus interessiert. Danke schonmal für bisherige Hilfe, *jiriki*
yo,
Also an einer Mengenoperatorenlösung wäre ich durchaus interessiert. Danke schonmal für bisherige Hilfe, *jiriki*
ok, ich habe mir noch keine kokreten gedanken gemacht, sag doch mal, welche Operatorem bezüglich von mengen kann den dein dbms ?
Ilja
ok, ich habe mir noch keine kokreten gedanken gemacht, sag doch mal, welche Operatorem bezüglich von mengen kann den dein dbms ?
Soweit ich weiss, unterstützt PostgreSQL den größten Teil der SQL-Syntax. Die Mengenoperatoren "UNION", "INTERSECT" und "EXCEPT" ("MINUS") auf jeden Fall. Gibts weitere?
Unter http://www.postgres.de/features.html steht da auch kurz und übersichtlich, was unterstützt wird.
Greets, *jiriki*
yo,
noch mal eine lösungsvorschlag ohne mengenoperatoren, der aber nur im speziellen fall funktioniert, nämlich dann, wenn die spalte ripped als aggregatfunktion MIN(), bzw. MAX() den wert "selbst geribbt auswirft. dann könnte man nämlich nur eine unterabfrage machen und hätte alle auf einmal.
den link schaue ich mir morgen an....
Ilja