sql查询各部分的执行顺序是什么,例如SELECT,DISTINCT,FROM,WHERE,GROUP BY,ORDER BY···
我搜索了大量站点,说ORDER BY是在SELECT之后执行的,如果是这样,则不应该执行诸如“从table1的order by column2顺序选择select column1”这样的简单查询,因为在执行SELECT之后,仅存在column1数据集,不能使用column2对数据集进行排序。但实际上它有效!
答案 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}
。现在,我们个人可能还a
和c
相等,但这与分析无关。
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 BY
。 DISTINCT
和DISTINCT
确实是同一件事-都明确地标识了一组列(GROUP BY
或由GROUP BY
子句中的列组成。您无法将SELECT
与SELECT
解除绑定,因为我们还必须计算聚集,并且聚集定义位于GROUP BY
子句中。对于分组列中明显的每个不同的值集,我们生成一个包含该值集以及任何计算的聚合的单个输出行。我们在此处生成SELECT
2 和 是查询其余部分可以观察到的结果集。原始结果集不在范围内。
{O(t1.a), O(e)}
-我们只能使用HAVING
子句 3 生成的那些列。但是同样,我们过滤行,而不是列。
和SELECT
也只能与ORDER BY
产生的列一起使用。
在SELECT
完成时,无论如何我们只有输出列,但输出处理还是一样。
希望从以上内容可以看到SELECT
可以以两种截然不同的方式工作;但是至少现在您知道差异和连锁反应的影响了。
1 我在这里即时编排术语,但是我使用SELECT
包装器来表示“此列将在最终结果集中”。
2 这是您似乎一直希望O()
表现出来的行为,只为后面的子句提供“可输出”行。
3 mysql包含SQL标准的扩展,该扩展允许未分组和未聚合的列显示为SELECT
子句谓词。它们已被有效地重写,可以在HAVING
子句中使用。