最后要对Nulls和Blanks进行排序,并阅读所有使用Coalesce函数或If by order by column的解决方案。
我的问题对我来说不起作用,因为我正在排序的列是由创建查询的PHP脚本动态指定的,而我的一些列在我的连接中的两个表中。
$sortcol="boat";
$sql= "SELECT fleet,b.boat as boat,owner FROM boats as b
LEFT JOIN owners as o ON b.boat=o.boat
ORDER BY $sortcol";
这很好用,我可以更改变量$ sortcol,我的输出列表效果很好,除了空值和空格位于顶部。
基于其他帖子,我试过这个
$sortcol="boat";
$sql= "SELECT fleet,b.boat as boat,owner FROM boats as b
LEFT JOIN owners as o ON b.boat=o.boat
ORDER BY IF($sortcol is NULL,1,0), $sortcol";
这会引发错误“ORDER BY子句中的列船不明确”。显然它需要b.boat按顺序,但由于我不会进入的原因是有问题的。 似乎无论何时我尝试在orderby子句中使用函数,我都不能使用列别名。
任何有关优雅解决方案的想法??
答案 0 :(得分:4)
ORDER BY
,只要您提供的名称不以任何方式处理(我无法做到)想到。也许其他人存在)。
一旦出现歧义,就会被拒绝。
这被接受(并且是多余的):
select b.id, a.name as name
FROM client AS a JOIN client AS b ON (a.id = b.id)
ORDER BY name, name;
COALESCE(name, '')
,name IS NULL
,name OR NULL
全部被拒绝。
显而易见的解决方案是为别名使用不同的名称,该名称不会出现在任何一个表中。
另一种可能性是创建嵌套查询:
SELECT * FROM ( your query here, without ORDER ) AS original
ORDER BY IF($sortcol is NULL,1,0), $sortcol;
那是:
$sortcol="boat";
$sql = <<<SQL
SELECT * FROM (
SELECT fleet,b.boat as boat,owner FROM boats as b
LEFT JOIN owners as o ON b.boat=o.boat
) AS original
ORDER BY IF($sortcol is NULL,1,0), $sortcol;
SQL;
答案 1 :(得分:1)
如果您有两个相似的列名,则必须在ORDER BY
中指定表。就这么简单。
您应该能够在SELECT
中使用其他别名来消除两个boat
列的歧义,然后在
$sortcol = "bboat";
$sql= "
SELECT
fleet,
/* Alias as bboat to disambiguate from b.boat and o.boat
b.boat as bboat,
owner
FROM
boats as b
LEFT JOIN owners as o ON b.boat=o.boat
ORDER BY IF($sortcol is NULL,1,0), $sortcol";
注意:如果$sortcol
是任何类型的用户输入的结果,则必须将其与可接受列名称的白名单进行比较,以防止SQL注入。
答案 2 :(得分:1)
根据ANSI SQL列别名(如果在ORDER BY
子句中使用)只能由它们自己使用 - 您不能使用别名来投影其他列或表达式。
因此,当按列表顺序使用name
并且不在表达式中时,它将被解释为对别名的引用。一旦在表达式中使用,它就无法解析为别名,因此MySQL会尝试查找要解析此问题的列。在您的查询范围内有两个这样的列,因此您会产生关于歧义的错误。
此分辨率行为可以从以下内容中看到(在MySQL和SQL Server中测试)
CREATE TABLE T
(
C INT,
D INT
)
INSERT INTO T
SELECT 1, 2 UNION ALL
SELECT 2, 1
SELECT C AS D, D AS C
FROM T
ORDER BY D
返回(按别名排序)
D C
----------- -----------
1 2
2 1
SELECT C AS D, D AS C
FROM T
ORDER BY D + 0
返回(按基列排序)
D C
----------- -----------
2 1
1 2