sqlmysql-error-1064sql-except

What's wrong with my SQL-EXCEPT-Operator?


When I select "BookID" from my tables "Stats" and "Book" I get desired results each like:

MariaDB [db1]> SELECT BookID From Book WHERE Author = 'AuthorX';
+--------+
| BookID |
+--------+
|   1003 |
+--------+


MariaDB [db1]> SELECT BookID From Stats WHERE BookID >= 1000;
+--------+
| BookID |
+--------+
|   1010 |
|   1005 |
|   1003 |
+--------+

But when I try to use the EXCEPT-operator, I get an error

MariaDB [db1]> (SELECT BookID From Stats WHERE BookID >= 1000)
     -> EXCEPT
     -> (SELECT BookID From Book WHERE Author = 'AuthorX');
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'EXCEPT (SELECT BookID From Book WHERE Author = 'AuthorX')' at line 1

What I hoped to be the output:

+--------+
| BookID |
+--------+
|   1010 |
|   1005 |
+--------+

What am I doing wrong? I tried with and without bracket, but got no idea, what to try next?

EDIT: Try with NOT IN

SELECT BookID From Stats WHERE BookID >= 1000 NOT IN  
(SELECT BookID From Book WHERE Author = 'AuthorX');

yields

+--------+
| BookID |
+--------+
|      3 |
|   1010 |
|   1005 |
|   1003 |
+--------+

EDIT2: "AND BookID NOT IN" for EXCEPT works

Still would love to know why EXCEPT doesn't

EDIT3: The Examples from https://mariadb.com/kb/en/library/except/ do work…

EDIT4: MariaDB Vers<10.3 does not have EXCEPT seems to be is the answer.

Still wonder why the examples work…


Solution

  • Remove the brackets.

    It looks "nicer" on three lines...

    SELECT `BookID` From `Stats` WHERE `BookID` >= 1000
    EXCEPT
    SELECT `BookID` From `Book`  WHERE `Author`  = 'AuthorX'
    

    It's much the same as you may see in UNION ALL...

    SELECT BookID From Book WHERE Title LIKE 'Harry Potter%'
    UNION ALL
    SELECT BookID From Book WHERE Author LIKE '%Toklien%'
    


    EDIT:

    Or just try an alternative expression (If on an older version of MariaDB)...

    SELECT BookID
      FROM Book
     WHERE BookID >= 1000
       AND BookID NOT IN (SELECT BookID
                            FROM Book
                           WHERE Author = 'AuthorX'
                         )
    

    Or...

    SELECT BookID
      FROM Book
     WHERE BookID >= 1000
       AND NOT EXISTS (SELECT *
                         FROM Book  lookup
                        WHERE lookup.Author = 'AuthorX'
                          AND lookup.BookID = Book.BookID
                      )
    

    Or...

    SELECT
      *
    FROM
    (
      SELECT BookID FROM Book WHERE BookID >= 1000
    )
      high_id
    LEFT JOIN
    (
      SELECT BookID FROM Book WHERE Author = 'AuthorX'
    )
      target_author
        ON target_author.BookID = high_id.BookID
    WHERE
      target_author.BookID IS NULL