Linuchs: mySQL: Mit einem Sub-Select mehrere Werte bekommen

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

  1. 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

    1. 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

  2. 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

    --
    sumpsi - posui - obstruxi
    1. 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