mySQL: 1241: Operand should contain 1 column(s)
Linuchs
- sql
Moin,
in einem Sub-Select suche ich pro Veranstalter ein zufälliges Audio-Element.
Von diesem brauche ich 4 Werte:
SELECT
MAX( CONCAT( trm1.zeit_neu,'|',trm1.id )) zeit_neu
...
# Zufalls-Media-Titel
,(
SELECT
CONCAT( med1.album, '@', med1.titel, '@', med1.url, '@', med1.youtube_id ) -- 2022-08-20 youtube_id
#,med1.album med_album
#,med1.titel med_titel
#,med1.url med_url
#,med1.youtube_id med_youtube_id
FROM bia_medien med1
WHERE med1.adress_id = adr1.id
AND med1.erreichbar_kz = '1'
# keine Weihnachtslieder im Sommer
AND ( med1.gueltig_von IS NULL
OR ( SUBSTR(med1.gueltig_von,6) <= SUBSTR(CURDATE(),6)
AND SUBSTR(med1.gueltig_bis,6) >= SUBSTR(CURDATE(),6) )
)
ORDER BY RAND()
LIMIT 0,1
) med_titel_url
FROM ...
Der Not gehorchend habe ich die 4 Werte per CONCAT zusammengefasst und trenne sie später wieder per explode. Wenn ich die auskommentierten Einzelwerte anspreche, kommt obiger Fehler.
Gibt es nur diese „Bastelversion“ mit CONCAT oder kann ich die vier Werte auch einzeln erhalten?
fragt Linuchs
Edit: Ist CONCAT auf eine Anzahl Werte begrenzt?
#CONCAT( med1.album, '@', med1.titel, '@', med1.url, '@', med1.youtube_id ) -- bleibt leer
CONCAT( med1.album, '@', med1.titel, '@', med1.url ) -- funktioniert
Uups, Geheimwissen: Note: If any of the expressions is a NULL value, it returns NULL
Die Bastelei wird immer abenteuerlicher, aber funktioniert:
CONCAT(
IF( med1.album IS NULL, '', med1.album ), '@',
IF( med1.titel IS NULL, '', med1.titel ), '@',
IF( med1.url IS NULL, '', med1.url ), '@',
IF( med1.youtube_id IS NULL, '', med1.youtube_id )
)
Bleibt die Frage, ob ich die Werte auch einzeln bekommen kann ohne CONCAT
CONCAT( IF( med1.album IS NULL, '', med1.album ), '@', IF( med1.titel IS NULL, '', med1.titel ), '@', IF( med1.url IS NULL, '', med1.url ), '@', IF( med1.youtube_id IS NULL, '', med1.youtube_id ) )
Naja. Man könnte auch vorbeugen wenn man die Hand auf dem Programm und den Tabellen hat. Ich weiß ja nicht, wie lang Deine Ergebnislisten sind, aber wenn die SEHR lang sind, dann kostet das den Prozessor auf dem Server einige Herzschläge extra.
Kann man vermeiden:
UPDATE med1 set album ='' where album =NULL;
ALTER TABLE med1 ALTER album SET DEFAULT '';
UPDATE med1 set titel ='' where titel =NULL;
ALTER TABLE med1 ALTER titel SET DEFAULT '';
UPDATE med1 set url ='' where url =NULL;
ALTER TABLE med1 ALTER url SET DEFAULT '';
UPDATE med1 set youtube_id ='' where youtube_id =NULL;
ALTER TABLE med1 ALTER youtube_id SET DEFAULT '';
Und dann das CONCAT() ohne das IF()-Geraffel.
P.S.
Hi,
in einem Sub-Select suche ich pro Veranstalter ein zufälliges Audio-Element.
Von diesem brauche ich 4 Werte:
Das klingt nicht nach subselect, sondern nach join.
Edit: Ist CONCAT auf eine Anzahl Werte begrenzt?
einige SQL-Dialekte haben bei 1000 Parametern ein Limit - ist mir bis jetzt nur bei IN() aufgefallen - concat mit so vielen Parametern hatte ich noch nicht …
cu,
Andreas a/k/a MudGuard
Das klingt nicht nach subselect, sondern nach join.
Ich arbeite haufenweise mit joins, muss mal nachdenken, warum ich das hier nicht gemacht habe ... (die Stelle ist uralt, nur das Feld youtube_id neu)
Vielleicht, weil ich ein ORDER BY RAND benötige? Kann ich per join einen Zufallswert ankoppeln?
Hallo Linuchs,
deine Query ist ohnehin total verquast und dürfte etliche "undefined" Komponenten enthalten.
adr1.id = $someId
, so dass die adr1.id für alle Sätze gleich ist?Meine Empfehlung wäre, zwei Querys zu machen.
Zunächst diese:
SELECT trm1.zeit_neu, trm1.id, adr1.id
FROM table1 trm1 JOIN table2 adr1 ON ...
WHERE ...
ORDER BY trm1.zeit_neu desc
LIMIT 1
Ich hab da jetzt irgendeinen JOIN hingeschrieben, das ist nur symbolisch und sieht in deiner Realität sicherlich anders aus.
Damit bekommst Du den MAX-Wert für zeit_neu und die trm1.id dazu, auf definierte Weise und ohne Stringverkettung. Wenn Du einen Index auf zeit_neu hast, führt diese Aufteilung auch zu einer Beschleunigung, weil er dann den Index dafür nutzen kann. Ob Du die adr1.id auch selektieren musst, hängt von Kontext ab den ich nicht kenne - ich hab sie mal reingeschrieben für den Fall, dass es mehrere adr1.id geben könnte.
Im zweiten Schritt machst Du dann den Zufalls-Select.
Das sind zwar zwei Queries, aber man muss nicht alles in einer Query zusammenpressen. Wenn dein SQL Server auf localhost läuft, ist die Abfragelatenz miminal. Wenn er auf einem anderen Server läuft, hast Du ein paar Millisekunden Latenz drin, aber bei einem stark belasteten System wird diese Latenz für die Ausführung anderer Requests genutzt, d.h. der Serverdurchsatz verringert sich nicht. Nur die Antwortzeit für einen einzelnen User, um ein kleines Bisschen. Das ist nicht schlimm. Aus Serversicht geht es Dir um die Optimierung des Durchsatzes, nicht unbedingt um schnellste Antwortzeit für einzelne User.
Rolf
Hallo Linuchs,
ein SELECT, mit dem Du einen Wert in die Select-Liste bringen willst, darf immer nur einen Wert liefern, das ist so.
Wie Mudguard sagte: Du musst einen JOIN machen. Ggf. einen LEFT JOIN.
Um NULL-Werte auf '' zu zwingen, kannst Du dein IF Konstrukt verwenden oder die IFNULL-Funktion (COALESCE geht auch).
Dein MAX sieht auch nach einem Hack aus, aber ich glaube, der ist hier ganz elegant.
Rolf