Auge: UNION in IN() als Teil einer WHERE-Klausel?

Beitrag lesen

Hallo

das [geht] nicht:

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)

Mit einem zusätzlichen Paar Klammern um den gesamten UNION-SELECT geht das auch (auch ohne Alias).

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)
)

Und so habe ich das, wie einen Zweig weiter zu lesen ist, auch gemacht.

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.

Für MySQL 5.5 (was bei mir läuft) und dein MySQL 5.6 wird das stimmen, aber ab MySQL 5.7 müssen die einzelnen SELECTs eingeklammert werden, wenn sie jeweils einzelne ORDER-BY- und LIMIT-Klauseln haben.

Aus der Doku zu UNION:

To apply ORDER BY or LIMIT to an individual SELECT, place the clause inside the parentheses that enclose the SELECT:

(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);

Note

Previous versions of MySQL may permit such statements without parentheses. In MySQL 5.7, the requirement for parentheses is enforced.

Nun bin ich – offensichtlich fälschlicherweise – davon ausgegangen, dass das auch vor 5.7 schon (in der von mir gewünschten Weise) fuunktioniert („Previous versions … may permit … statements without parentheses … MySQL 5.7 the requirement … is enforced“). Das, zumal ich die auf den verschiedenen Zielsystemen installierten MySQL-Versionen nicht kenne, die Klammerpflicht von/ab MySQL 5.7 also durchaus zuschlagen könnte.

Ich habe mittlerweile zwar eine funktionierende Lösung, werde deinen Query aber trotzdem ausprobieren.

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 )

Danke auch dir.

Tschö, Auge

--
Wenn man ausreichende Vorsichtsmaßnahmen trifft, muss man keine Vorsichtsmaßnahmen mehr treffen.
Toller Dampf voraus von Terry Pratchett