为什么给定的语法在mysql中有效?

时间:2014-03-31 00:55:38

标签: mysql sql

another answer中,我发现了一种奇怪的语法:

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

虽然很好地由mysql执行。

为什么我认为它应该失败:

  1. 子查询没有别名
  2. 整个查询缺少SELECT子句
  3. 我发现它出乎意料地运行,并且没有解释它为何起作用。

    它不符合https://dev.mysql.com/doc/refman/5.5/en/select.html

    上定义的语法

    那么,为什么它有效?有没有参考?

2 个答案:

答案 0 :(得分:6)

这是替代UNION语法,带有最终ORDER BY

这就是两个选项之间的这种联合看起来像:

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

这就是 one 选择之间的这种联合看起来像:

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

根本与子查询无关。

这在MySQL中没有记载,但从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; }
        ;

答案 1 :(得分:1)

当您想要对UNION的最终结果进行排序时,语法很有用。

以下内容仅排序最后一个SELECT:

SELECT …
UNION
SELECT …
UNION
SELECT … ORDER BY views

但这会对整个结果进行排序:

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

您正在执行类似此查询的操作,但您只有一个SELECT。