Sorting Nulls last

狂风中的少年 提交于 2019-12-04 07:16:46

You're right. For no reason that I can fathom, MySQL accepts an ambiguous ORDER BY as long as the name you supply is not handled in any way (no way that I could think of. Maybe others exist).

As soon as it is, ambiguousness gets rejected.

This is accepted (and redundant):

select b.id, a.name as name
    FROM client AS a JOIN client AS b ON (a.id = b.id)
    ORDER BY name, name;

while COALESCE(name, ''), name IS NULL, name OR NULL are all rejected.

The obvious solution is to use a different name for the alias, one that does not appear in either table.

Another possibility would be to create a nested query:

SELECT * FROM ( your query here, without ORDER ) AS original
ORDER BY IF($sortcol is NULL,1,0), $sortcol;

That is:

$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;

You MUST specify the table in the ORDER BY if you have two similar column names. It's that simple.

You should be able to use a different alias in the SELECT which disambiguates from both boat columns and then use that in the

$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";

Note: if $sortcol is the result of any kind of user input, it is necessary to compare it against a whitelist of acceptable column names to prevent SQL injection.

According to ANSI SQL column aliases if used in the ORDER BY clause can only be used by themselves - you can't use the aliases to project other columns or expressions.

So when name is used in the order by list and is not in an expression it is interpreted as a reference to the alias. Once used in an expression then it can't resolve to an alias so MySQL tries to find a column to resolve this to. There are two such columns in scope in your query hence the error you get about ambiguity.

This resolution behavior can be seen from the following (tested in MySQL and 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

Returns (ordered by alias)

D           C
----------- -----------
1           2
2           1

SELECT C AS D, D AS C
FROM T 
ORDER BY D + 0

Returns (ordered by base column)

D           C
----------- -----------
2           1
1           2
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!