sql查询各部分的执行顺序是什么

时间:2019-02-20 05:51:24

标签: mysql sql

sql查询各部分的执行顺序是什么,例如SELECT,DISTINCT,FROM,WHERE,GROUP BY,ORDER BY···

我搜索了大量站点,说ORDER BY是在SELECT之后执行的,如果是这样,则不应该执行诸如“从table1的order by column2顺序选择select column1”这样的简单查询,因为在执行SELECT之后,仅存在column1数据集,不能使用column2对数据集进行排序。但实际上它有效!

2 个答案:

答案 0 :(得分:0)

考虑查询-

select distinct <columns> from 
table1 t1 inner join t2 
on t1.col=t2.col
where <conditions>
group by <col>
having <conditions>

执行顺序为-

> From
> ON
> JOIN
> Where
> group by
> Having
> Select
> Distinct
> Order By

答案 1 :(得分:0)

让我们针对两个表分解两个查询,两个表都包含两列。首先,我们将做一个简单的事情:

SELECT t1.a,t2.d + 6 as e
FROM
    table1 t1
       inner join
    table2 t2
       on
           t1.a = t2.c
WHERE
    t1.b = 2
ORDER BY
    t2.c

在完成每个子句时,请考虑什么是“范围内”:

  • FROM table1 t1-至此,我们的结果集包含两列-{t1.a, t1.b}

  • INNER JOIN table2 t2 ON ...-我们现在有一个包含四列的结果集-T1.a, t1.b, t2.c, t2.d}。现在,我们个人可能还ac相等,但这与分析无关。

  • WHERE-尽管WHERE可以从查询中过滤,但它不会更改构成结果集的列集-仍然{ {1}}。

  • {t1.a, t1.b, t2.c, t2.d}-我们没有SELECT子句,因此这里GROUP BY子句的工作是a)为输出标记某些列,b)可能添加一些其他列,这些列的值将被计算。那就是我们这里的东西。我们最终得到了一组SELECT 1

  • {O(t1.a), t1.b, t2.c, t2.d, O(e = t2.d +6)}-现在我们按ORDER BY进行订购,尽管它不会被输出,但仍在范围内

  • 最后,此查询的输出已传递(从技术上通过游标),并且仅包含t2.c。这些列不再与它们的“来源表”相关联,并且非输出列消失在以太币中。


{a, e}
  • SELECT t1.a,SUM(t2.d) as e FROM table1 t1 inner join table2 t2 on t1.a = t2.c GROUP BY t1.a HAVING e > 5 ORDER BY t1.a / FROM子句与以前的子句相同,因此以相同的分析为准。同样,我们没有JOIN子句,但它与列集无关。我们有WHERE

  • {t1.a, t1.b, t2.c, t2.d} / SELECT / GROUP BYDISTINCTDISTINCT确实是同一件事-都明确地标识了一组列(GROUP BY或由GROUP BY子句中的列组成。您无法将SELECTSELECT解除绑定,因为我们还必须计算聚集,并且聚集定义位于GROUP BY子句中。对于分组列中明显的每个不同的值集,我们生成一个包含该值集以及任何计算的聚合的单个输出行。我们在此处生成SELECT 2 是查询其余部分可以观察到的结果集。原始结果集不在范围内。

  • {O(t1.a), O(e)}-我们只能使用HAVING子句 3 生成的那些列。但是同样,我们过滤,而不是列。

  • SELECT也只能与ORDER BY产生的列一起使用。

  • SELECT完成时,无论如何我们只有输出列,但输出处理还是一样。


希望从以上内容可以看到SELECT可以以两种截然不同的方式工作;但是至少现在您知道差异和连锁反应的影响了。


1 我在这里即时编排术语,但是我使用SELECT包装器来表示“此列将在最终结果集中”。

1 >

2 这是您似乎一直希望O()表现出来的行为,只为后面的子句提供“可输出”行。

3 包含SQL标准的扩展,该扩展允许未分组和未聚合的列显示为SELECT子句谓词。它们已被有效地重写,可以在HAVING子句中使用。