UNION in IN() als Teil einer WHERE-Klausel?
bearbeitet von James MoriartySehr subtiler Fehler :)
Das geht:
~~~sql
(SELECT id FROM entries WHERE spam = 0 ORDER BY time DESC LIMIT 6)
UNION
(SELECT id FROM entries WHERE spam = 0 ORDER BY edited DESC LIMIT 6)
~~~
{: .good}
Aber das nicht:
~~~sql
SELECT * FROM
(SELECT id FROM entries WHERE spam = 0 ORDER BY time DESC LIMIT 6)
UNION
(SELECT id FROM entries WHERE spam = 0 ORDER BY edited DESC LIMIT 6)
~~~
{: .bad}
Und die Meldung lautet hier: #1248 - Every derived table must have its own alias !
Mit einem Alias geht der Fehler weg:
~~~sql
SELECT * FROM
(SELECT id FROM entries WHERE spam = 0 ORDER BY time DESC LIMIT 6) E
UNION
(SELECT id FROM entries WHERE spam = 0 ORDER BY edited DESC LIMIT 6)
~~~
Aber das ist ja für die IN-Klausel nicht das, was Du willst. Und einen Alias-Namen DIREKT innerhalb einer IN Klausel nimmt der Bursche auch nicht.
Das Problem sind die Klammern um die beiden Subselects, die sind nicht nötig und führen nur dazu, dass sie als namenspflichtige Subselects behandelt werden. Das brauchst Du aber gar nicht.
~~~sql
SELECT id, user_id, name, time, subject, category
FROM entries LEFT JOIN userdata ON userdata.user_id = entries.user_id
WHERE entries.id IN (SELECT id FROM entries WHERE spam = 0 ORDER BY time DESC LIMIT 6 UNION SELECT id FROM entries WHERE spam = 0 ORDER BY edited DESC LIMIT 6)
~~~
behebt das Alias-Problem, allerdings liefert mir MySQL 5.6.33 dann diese Meldung:
`This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'`{: .bad }
Welche MySQL Version das unterstützt, habe ich nicht wirklich herausgefunden, aber wir haben Glück, es gibt einen Workaround ([Quelle](http://stackoverflow.com/questions/7124418/mysql-subquery-limit)). Man tarnt die LIMITs durch einen dazwischengeschobenen Subselect:
~~~sql
SELECT id, user_id, name, time, subject, category
FROM entries LEFT JOIN userdata ON userdata.user_id = entries.user_id
WHERE entries.id IN (
SELECT id
FROM (SELECT id FROM entries WHERE spam = 0 ORDER BY time DESC LIMIT 6
UNION
SELECT id FROM entries WHERE spam = 0 ORDER BY edited DESC LIMIT 6) X )
~~~
{: .good}
Beachte das X zwischen den beiden letzten Klammern, sonst kommt wieder die Meldung mit dem fehlenden Alias.
Getestet auf MySQL 5.6.33.
_Rolf_