mySQL: Mit einem Sub-Select mehrere Werte bekommen
Linuchs
- sql
Moin,
ich selektiere Adressen. Pro Adresse gibt es 0..n Hörproben. Davon möchte ich eine zufällige: Den Titel und die Web-Adresse
SELECT
...
,(
SELECT
med1.titel audio_titel
,med1.url audio_url
#CONCAT( med1.titel, '@', med1.url )
FROM ".$db[0]['medien']." med1
WHERE med1.adress_id = adr1.id
AND LOWER( med1.url ) LIKE '%.mp3'
AND med1.erreichbar_kz = 1 -- Medium muss erreichbar sein
ORDER BY RAND()
LIMIT 0,1
)
...
SQL Fehlermeldung: 1241: Operand should contain 1 column(s)
Zuvor hatte ich die beiden Werte mit CONCAT gebündelt und per PHP wieder getrennt. Doch nun habe ich eine gemeinsame PHP-Auswertung für verschiedene SELECTs vergleichbar mit UNION.
Gruß, Linuchs
Hi,
SELECT ... ,( SELECT med1.titel audio_titel ,med1.url audio_url #CONCAT( med1.titel, '@', med1.url ) FROM ".$db[0]['medien']." med1 WHERE med1.adress_id = adr1.id AND LOWER( med1.url ) LIKE '%.mp3' AND med1.erreichbar_kz = 1 -- Medium muss erreichbar sein ORDER BY RAND() LIMIT 0,1 ) ...
SQL Fehlermeldung:
1241: Operand should contain 1 column(s)
Zuvor hatte ich die beiden Werte mit CONCAT gebündelt und per PHP wieder getrennt. Doch nun habe ich eine gemeinsame PHP-Auswertung für verschiedene SELECTs vergleichbar mit
Spontan würde ich sagen: statt sub-select mit join arbeiten.
cu,
Andreas a/k/a MudGuard
Hallo MudGuard
Spontan würde ich sagen: statt sub-select mit join arbeiten.
Join begrenzen? Ich greife die Idee gerne auf, recherchiere und stoße zu dieser Raterunde. Rate mit, experimentiere zweieinhalb Stunden und komme nicht zum Ziel.
Die beiden gesuchten Werte titel und url sind NULL
LEFT JOIN
(
SELECT
adress_id
,titel
,url
FROM ".$db[0]['medien']."
WHERE erreichbar_kz = 1 -- Medium muss erreichbar sein
AND LOWER( url ) LIKE '%.mp3'
#AND adress_id = adr1.id
ORDER BY RAND()
LIMIT 1
) med1
ON med1.adress_id = adr1.id
Ich denke, wenn ich vor dem Abgleich mit adr1.id die Treffer (alle erreichbaren mp3-Dateien) auf 1 beschränke, ist sehr unwahrscheinlich, dass diese eine zum Mitglied adr1 passt.
Nehme ich den Abgleich in die Klammer, kommt der Fehler 1054: Unknown column 'adr1.id' in 'where clause'
Linuchs
Hallo Linuchs,
ich komm zum Verrecken nicht mehr drauf wie es geht - aber es gab ein neueres SQL Sprachfeature, mit dem man Wertegruppen bilden konnte und solche Wertegruppen auch aus einem Subselect zurückgeben.
Ich weiß auch nicht, ob das - wenn überhaupt - in MYSQL unterstützt wird. Welche Version verwendest Du da?
Die einfachste - nicht unbedingt performanteste - Lösung könnte eine Mischung aus Subselect und Join sein. Haben deine Medien auch eine ID? Oder zumindest eine Spalte, die zusammen mit der adress_id eine eindeutige Identifikation erlaubt? Du könntest dann im Subselect die Spalte herausholen, die das Medium eindeutig identifiziert, und mit einem Join die andere Spalte hinzuholen.
SELECT x.foo, x.bar, x.audio_titel, y.med1_url as audio_url
FROM (SELECT
adr1.id as adr_id
adr1.foo
, adr1.bar
, (SELECT med1.titel
FROM ".$db[0]['medien']." med1
WHERE med1.adress_id = adr1.id
AND ... ORDER BY RAND() LIMIT 0,1) audio_titel
) x
LEFT JOIN ".$db[0]['medien']." y ON x.adr_id = y.adress_id and x.audio_titel = y.audio_titel
Nein, das ist nicht schön. Aber was besseres fällt mir - angesichts des ORDBER BY RAND() LIMIT 0,1 im Subselect, auch nicht ein.
Ob man mit den Window-Funktionen in MySQL 8 etwas reißen kann (dieses ganze OVER Zeugs), das weiß ich auch nicht. So vertraut bin ich damit nicht, und auf Anhieb fiel mir beim Handbuchüberfliegen nichts auf.
Rolf
Hallo Rolf,
heute habe ich die Lösung vergeblich gesucht und bin etwas abgekämpft. Probiere deinen Vorschlag morgen aus.
Welche Version verwendest Du da?
MySQL-Vers.=[10.1.37-MariaDB-0+deb9u1]
Linuchs