Dynamic ORDER BY with CASE statement in SQL Server - data type issues
In Microsoft SQL Server 2005 Transact-SQL (and prior versions), you can make a dynamic ORDER BY based on a variable like so:
You can
or
, sorting will fail with SQL error similar to the following:
in the first case and
in the second if the optimizer encounters data that can't be converted to integer. The explanation is found in the SQL Server books online:
This means that you cannot mix types in your CASE statement which cannot be implicitly converted into the types with higher precedence according to the following list (also found in Books Online):
- user-defined data types (highest)
- sql_variant
- xml
- datetime
- smalldatetime
- float
- real
- decimal
- money
- smallmoney
- bigint
- int
- smallint
- tinyint
- bit
- ntext
- text
- image
- timestamp
- uniqueidentifier
- nvarchar
- nchar
- varchar
- char
- varbinary
- **binary **(lowest)
Because datetime and smalldatetime with their high precedence are internally stored as 4-byte and 2-byte integers respectively, you can almost always mix integers with datetime or smalldatetime. Floating numbers don't mix unless they can be cleanly converted to integers. As a workaround you could use table variables or Common Table Expressions (CTE, new in SQL Server 2005), insert the ordered data, and query these instead. The better solution with less overhead might be to group the CASE statements according to data types. The above example would look like this:
Posted: 14 November 2006