UNION in IN() als Teil einer WHERE-Klausel?
bearbeitet von AugeHallo
> das [geht] 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}
Mit einem zusätzlichen Paar Klammern um den gesamten UNION-SELECT geht das auch (auch ohne Alias).
~~~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)
)
~~~
{: .good}
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, 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:
~~~sql
(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.
> ~~~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}
Danke auch dir.
Tschö, Auge
--
Wenn man ausreichende Vorsichtsmaßnahmen trifft, muss man keine Vorsichtsmaßnahmen mehr treffen.
Toller Dampf voraus von Terry Pratchett
UNION in IN() als Teil einer WHERE-Klausel?
bearbeitet von AugeHallo
> das [geht] 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}
Mit einem zusätzlichen Paar Klammern um den gesamten UNION-SELECT geht das auch ohne Alias.
~~~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)
)
~~~
{: .good}
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, 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:
~~~sql
(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.
> ~~~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}
Danke auch dir.
Tschö, Auge
--
Wenn man ausreichende Vorsichtsmaßnahmen trifft, muss man keine Vorsichtsmaßnahmen mehr treffen.
Toller Dampf voraus von Terry Pratchett