Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why the given syntax is valid in mysql?

Tags:

sql

mysql

In another answer I've spotted a weird syntax:

(SELECT * FROM `articles` 
 WHERE date >= UNIX_TIMESTAMP(DATE(NOW() - INTERVAL 30 DAY))
 ORDER BY `views` DESC 
 LIMIT 20
) ORDER by `views` ASC

which was executed by mysql well though.

Why I think it should fail:

  1. The subquery doesn't have alias
  2. The whole query lacks SELECT clause

I find it unexpected to run and don't have an explanation why it works.

It does not fit the grammar defined on https://dev.mysql.com/doc/refman/5.5/en/select.html

So, why is it valid? Any references?

like image 577
zerkms Avatar asked Mar 31 '14 00:03

zerkms


People also ask

Which statements are not supported as prepared in MySQL?

Other statements are not supported. For compliance with the SQL standard, which states that diagnostics statements are not preparable, MySQL does not support the following as prepared statements: Statements containing any reference to the warning_count or error_count system variable.

What is the data type in MySQL?

The data type is a guideline for SQL to understand what type of data is expected inside of each column, and it also identifies how SQL will interact with the stored data. In MySQL there are three main data types: string, numeric, and date and time. A FIXED length string (can contain letters, numbers, and special characters).

Can I use MySQL_stmt_prepare () in C API?

For example, you cannot use the mysql_stmt_prepare () C API function to prepare a PREPARE , EXECUTE, or DEALLOCATE PREPARE statement. SQL syntax for prepared statements can be used within stored procedures, but not in stored functions or triggers.

How does MySQL interpret length specifications for column data types?

For definitions of binary string columns ( BINARY , VARBINARY, and the BLOB types), MySQL interprets length specifications in byte units. Column definitions for character string data types CHAR , VARCHAR, the TEXT types, ENUM , SET, and any synonyms) can specify the column character set and collation: CHARACTER SET specifies the character set.


2 Answers

It's the alternative UNION syntax with a final ORDER BY.

This is what such a union between two selects looks like:

(SELECT ...)
UNION
(SELECT ...) ORDER BY ... LIMIT ...

And this is what such a union between one select looks like:

(SELECT ...) ORDER BY ... LIMIT ...

Not related to subqueries at all.

This isn't documented in MySQL, but is obvious from the grammar:

top_level_select_init:
        SELECT_SYM
        {
            Lex->sql_command= SQLCOM_SELECT;
        }
        select_init2
        | '(' select_paren ')' union_opt
        ;


/* Need select_init2 for subselects. */
union_select_init:
        SELECT_SYM select_init2
        | '(' select_paren ')' union_opt
        ;

...

union_opt:
        /* Empty */ { $$= 0; }
        | union_list { $$= 1; }
        | union_order_or_limit { $$= 1; }
        ;
like image 83
Eevee Avatar answered Oct 04 '22 19:10

Eevee


The syntax is useful when you want to sort the end result of the UNION.

The following would sort only the last SELECT:

SELECT …
UNION
SELECT …
UNION
SELECT … ORDER BY views

But this would sort the whole result:

(SELECT …)
UNION
(SELECT …)
UNION
(SELECT …) ORDER BY views

You're doing something like this query, but you've got just one SELECT.

like image 38
Bill Karwin Avatar answered Oct 04 '22 17:10

Bill Karwin