SQL:合并 'AS' 和 'WHERE'

SQL: Combining 'AS' and 'WHERE'

我有一列包含 4 组版本号(即 13.8.0.2629.0.0.0)。

我有以下代码选择版本并将其分成 4 组并从最旧到最新排序

SELECT Version,
SUBSTRING_INDEX( `version` , '.', 1 )*1 as A,
SUBSTRING_INDEX(SUBSTRING_INDEX( `version` , '.', 2 ),'.',-1)*1 as B, 
SUBSTRING_INDEX(SUBSTRING_INDEX( `version` , '.', -2 ),'.',1)*1 as C,
SUBSTRING_INDEX( `version` , '.', -1 )*1 as D
FROM Test
WHERE A > 13
order by 
A,B,C,D

我正在尝试过滤结果,即搜索第一个版本 (A) > 14 的位置,但我得到 Unknown column 'A' in 'where clause'。我是否错误地使用了 AS 关键字?

这是一个link给我的SQL Fiddle

您可能会发现 HAVING 子句很有用:

SELECT Version,
SUBSTRING_INDEX( `version` , '.', 1 )*1 as A,
SUBSTRING_INDEX(SUBSTRING_INDEX( `version` , '.', 2 ),'.',-1)*1 as B, 
SUBSTRING_INDEX(SUBSTRING_INDEX( `version` , '.', -2 ),'.',1)*1 as C,
SUBSTRING_INDEX( `version` , '.', -1 )*1 as D
FROM Test
HAVING A > 13
order by 
A,B,C,D

Heres a working demonstration.


根据 MySQL SELECT documentationWHERE 子句无法访问别名:

It is not permissible to refer to a column alias in a WHERE clause, because the column value might not yet be determined when the WHERE clause is executed.

但是可以通过HAVING子句访问:

A HAVING clause can refer to any column or alias named in a select_expr in the SELECT list or in outer subqueries, and to aggregate functions.

另请注意:

... the SQL standard requires that HAVING must reference only columns in the GROUP BY clause or columns used in aggregate functions. To accommodate both standard SQL and the MySQL-specific behavior of being able to refer columns in the SELECT list, MySQL 5.0.2 and up permit HAVING to refer to columns in the SELECT list, columns in the GROUP BY clause, columns in outer subqueries, and to aggregate functions.

如需进一步参考,请参阅 Why does MySQL allow HAVING to use SELECT aliases?

SELECT MySQL 声明的文档摘录:

A select_expr can be given an alias using AS alias_name. The alias is used as the expression's column name and can be used in GROUP BY, ORDER BY, or HAVING clauses.

以及下面的几段:

It is not permissible to refer to a column alias in a WHERE clause, because the column value might not yet be determined when the WHERE clause is executed.

你问题的答案

如上面引用的片段中所述,不,您不能在 WHERE 子句中使用 A 别名。您必须改用别名表达式。

SELECT Version,
SUBSTRING_INDEX( `version` , '.', 1 )*1 as A,
SUBSTRING_INDEX(SUBSTRING_INDEX( `version` , '.', 2 ),'.',-1)*1 as B, 
SUBSTRING_INDEX(SUBSTRING_INDEX( `version` , '.', -2 ),'.',1)*1 as C,
SUBSTRING_INDEX( `version` , '.', -1 )*1 as D
FROM Test
WHERE SUBSTRING_INDEX( `version` , '.', 1 )*1 > 13
order by 
A,B,C,D