Reputation: 89
Although this technique works great for standard columns, I have run into something I don't understand. I am rewriting results in my query for reporting purposes and need to order by the aliased column 'PARENT', like so:
select fun.MODULE_ID
, fun.FUNCTION_ID
, COALESCE(fun.parent_function, fun2.function_id) as PARENT
, fun.DESCRIPTION
, fun.FUNCTION_PURPOSE
from MODULE_FUNCTION fun
LEFT JOIN MODULE_FUNCTION fun2
ON fun.function_id = fun2.function_id
AND fun2.function_id IN (SELECT parent_function FROM MODULE_FUNCTION)
ORDER BY MODULE_ID
, PARENT
, FUNCTION_ID
This works great, but my column 'PARENT_FUNCTION' and its alias 'PARENT' contain nulls. I would like these to be at the bottom. So when I do this:
ORDER BY MODULE_ID
, case when PARENT is null then 1 else 0 end, PARENT
, FUNCTION_ID
I get " Invalid column name 'PARENT'. "
Any ideas? (Still very new with SQL!)
Upvotes: 1
Views: 374
Reputation: 11283
SQL Server won't let you use a column alias elsewhere in the query except in an ORDER BY
clause (but not in an expression within ORDER BY
), so you have to retype the original column definition. For a more in depth explanation of this (much better than I could give) please see this page
try this:
ORDER by MODULE_ID
, case when COALESCE(fun.parent_function, fun2.function_id) is null then 1 else 0 end
, FUNCTION_ID
Upvotes: 3
Reputation: 453648
When using a column alias in an ORDER BY
clause it can only be used on its own. If you try and use it in an expression SQL Server will try and resolve it to a column in one of the base tables instead.
For example
DECLARE @T TABLE(X INT, Y int)
INSERT INTO @T
VALUES (1,3),(2,2),(3,1)
SELECT X AS Y
FROM @T
ORDER BY Y
Y
-----------
1
2
3
SELECT X AS Y
FROM @T
ORDER BY Y + 0
Y
-----------
3
2
1
The first result set is ordered by the column alias and the second by the column Y
in the base table.
You can either repeat the underlying expression as in the other answer or use a derived table / cte to project the column then you can use that projected column in an expression in an order by
.
;WITH CTE
AS (SELECT fun.MODULE_ID,
fun.FUNCTION_ID,
COALESCE(fun.parent_function, fun2.function_id) AS PARENT,
fun.DESCRIPTION,
fun.FUNCTION_PURPOSE
FROM MODULE_FUNCTION fun
LEFT JOIN MODULE_FUNCTION fun2
ON fun.function_id = fun2.function_id
AND fun2.function_id IN (SELECT parent_function
FROM MODULE_FUNCTION))
SELECT *
FROM CTE
ORDER BY MODULE_ID,
CASE
WHEN PARENT IS NULL THEN 1
ELSE 0
END,
PARENT,
FUNCTION_ID
Upvotes: 3