ORDER BY items must appear in the select list if SELECT DISTINCT is specified SELECT DISTINCT *
    FROM (
        SELECT a.Title, a.ID FROM TableA a
        LEFT JOIN TableB b 
        ON a.ID = b.XID) c
    ORDER BY 
        CASE WHEN c.ID &gt; 10 THEN c.Title
        ELSE c.ID
        END
    ASC


And if I move DISTINCT to nested select, then both ID and Title should be in same type, e.g: INT, but they are not.

Both ID and Title are in the selected columns, what is the problem?

Also with this change CASE WHEN 1 &lt;&gt; 1 query runs without problem.
The real issue is caused by data type conversion. If you add this expression to the select list:

CASE WHEN c.ID &gt; 10 THEN c.Title
        ELSE c.ID
        END


you will see another error. Something like: "Conversion failed when converting the nvarchar value 'Some title' to data type int". According to data type precedence when you compare varchar with int values (SQL Server will need to compare Title with ID to sort your final result set) varchar should be converted to int because int has higher precedence.
https://docs.microsoft.com/en-us/sql/t-sql/data-types/data-type-precedence-transact-sql?view=sql-server-ver15