首页 > 解决方案 > mysql SELECT 和 WHERE 通常如何工作以及添加列时如何工作?

问题描述

我是 mysql 的新手,我不知道术语,所以我会尽量说话。这是我的问题:

我有works表,它有列:id、、datedone

+----+---------------------+------+
| id |        date         | done |
+----+---------------------+------+
|  1 | 2020-05-01 14:22:34 |   10 |
|  2 | 2020-05-02 14:22:45 |   50 |
|  3 | 2020-05-03 14:23:00 |   30 |
|  4 | 2020-05-04 14:23:13 |  100 |
|  5 | 2020-05-05 14:23:24 |   25 |
+----+---------------------+------+

我想用 +1 新列选择所有这些,命名为cummulative_done. 我使用这个 sql 命令来获得我想要的结果。

SET @cdone := 0;
SELECT *, (@cdone := @cdone + done) as cummulative_done
FROM works;

结果:

+----+---------------------+------+------------------+
| id |        date         | done | cummulative_done |
+----+---------------------+------+------------------+
|  1 | 2020-05-01 14:22:34 |   10 |               10 |
|  2 | 2020-05-02 14:22:45 |   50 |               60 |
|  3 | 2020-05-03 14:23:00 |   30 |               90 |
|  4 | 2020-05-04 14:23:13 |  100 |              190 |
|  5 | 2020-05-05 14:23:24 |   25 |              215 |
+----+---------------------+------+------------------+

然后,我希望cummulative_done使用 sql过滤该结果WHERE。在我第一次尝试时,我使用了这个 sql 命令。

SET @cdone := 0;
SELECT *, (@cdone := @cdone + done) as cummulative_done
FROM works
WHERE cummulative_done <= 100;

它给了我错误:Error in query (1054): Unknown column 'cummulative_done' in 'where clause'

之后,我在谷歌上搜索并使用此 sql 命令得到了解决方案。

SET @cdone := 0;
SELECT *, (@cdone := @cdone + done) as cummulative_done
FROM works
WHERE @cdone + done <= 100;

结果:

+----+---------------------+------+------------------+
| id |        date         | done | cummulative_done |
+----+---------------------+------+------------------+
|  1 | 2020-05-01 14:22:34 |   10 |               10 |
|  2 | 2020-05-02 14:22:45 |   50 |               60 |
|  3 | 2020-05-03 14:23:00 |   30 |               90 |
+----+---------------------+------+------------------+

它给了我想要的结果,但我不明白为什么它有效,为什么我的无效。

从那,我意识到我对sql的理解SELECTWHERE错误的。谁能向我解释一下 sqlSELECTWHERE一般是如何工作的?之后,请解释为什么我的第一次尝试不起作用以及解决方案为何起作用。

如果可以,我更喜欢step-by-stepdeep解释,但仍然easy to understand。谢谢。

标签: mysql

解决方案


查看 MySQL 语句的执行顺序。WHERE之前执行,SELECT因此您无法按稍后定义的列进行过滤。

更多信息: MySQL 查询/子句执行顺序

下一行变量的每次迭代都会随着前一行@cdone的值而增加,done因此该条件适用于结果。对于每一行的WHERE/SELECT执行顺序保持不变,但对每一行逐一执行。

WHERE 子句(如果给定)指示行必须满足才能被选择的一个或多个条件。where_condition 是一个表达式,对于要选择的每一行计算结果为真。如果没有 WHERE 子句,该语句将选择所有行。

您可以修改您的代码。

SET @cdone := 0;
SELECT *, @cdone as cummulative_done
FROM works
WHERE (@cdone := @cdone + done) <= 100;

https://dev.mysql.com/doc/refman/8.0/en/select.html


推荐阅读