SET @rownum := -1;
SELECT
round(AVG(t.LAT_N),4)
FROM
(
SELECT
@rownum := @rownum + 1 AS rownum,
STATION.LAT_N AS LAT_N
FROM
STATION
ORDER BY STATION.LAT_N
) AS t
WHERE
t.rownum IN (
CEIL(@rownum/2),
FLOOR(@rownum/2)
)
;
在上面的代码中,
就像在Python中写一些东西:i = i + 1
在i的值的for循环上下文中有意义,但上面的SQL代码中的for循环在哪里(select执行for循环?)?
此外,在WHERE子句中,@ rownum被用作表示表中最大行的变量,而在SELECT中,它被用作表示当前行的单个行号的变量被迭代。为什么呢?
据我了解,@ runum声明了一个持久存入WHERE子句的实例变量。那么做“AS rownum”有什么意义呢?
答案 0 :(得分:1)
此查询使用行号会话变量来计算表中的LAT_N
中值。考虑一个简单的场景,其中LAT_N
值的范围是1到10.然后,在分配行号(基于零)之后,我们将得到以下中间表:
LAT_N | rownum
1 | 0
2 | 1
3 | 2
4 | 3
5 | 4
6 | 5
7 | 6
8 | 7
9 | 8
10 | 9
在迭代内部子查询的最后,从@rownum
开始的-1
的值为9
。外部查询如下所示:
SELECT ROUND(AVG(t.LAT_N), 4)
FROM
(the above table) t
WHERE
t.rownum IN (CEIL(@rownum/2), FLOOR(@rownum/2));
因此,这取了LAT_N
的平均值,其中生成的行号为4
或5
。这将产生中值5.5
。请注意,对于奇数个记录,天花板和楼层都会产生相同的数字,并且只有一个真正的中间值。
答案 1 :(得分:0)
是的,这个@rownum
只使用一个动态变量作为列值,只有当你指定一个别名并在 HAVING 子句中测试它时,它才可以用作行索引。改为使用子查询。
select
没有循环,指针会分配给数据中跟踪的每一行,而@rownum
运算符已将:=
分配给上一个值。
您的查询可能是这样的,其中条件可能会有所不同,但方法是完全概念化的。如果您指定别名或子查询,则可以将其用作行索引。
注意:那里,在第二个条件下你不能使用@rownum 条件为false,因为它包含最后一个if中的特定值 任何条件不匹配,那么它将不返回任何数据,但如果你的 条件为真然后您可以使用它。
答案 2 :(得分:0)
@rownum:=@rownum+1
完全像i = i + 1
一样工作。 AS rownum
正在为此字段添加别名(另请参阅:alias syntax)。您可以为任何字段或表创建别名。实际上,SQL语句中有两个select
个查询。
SELECT
@rownum := @rownum + 1 AS rownum,
STATION.LAT_N AS LAT_N
FROM
STATION
ORDER BY STATION.LAT_N
这是一个所谓的子查询,其结果将被视为主查询检索信息的表。
对于子查询,您没有给出WHERE
子句,因此它将在STATION
表中逐行检索每个记录。由于您将@rownum := @rownum + 1 AS rownum
写为第一个结果列,因此每行@rownum
将增加1。所以,它只是像for循环一样工作。
在这种情况下,子查询将始终在主查询之前运行。因此,在主查询的WHERE
子句中,@rownum
已经等于STATION
表的行数。