Site sponsored by: Idera Try Idera’s new SQL admin toolset
SQL Server Performance

  • Home
  • Articles
  • Forums
  • Tips
  • Quiz
  • FAQ's
  • Blogs
  • Software
  • Books
  • About Us
RSS Feeds
Sign in | Join


FAQ Topics

All FAQ's
General DBA
General Developer
DBA Performance Tuning
Developer Performance Tuning
Clustering
Error Messages

SQL Server 2008 - Worth the Wait

SQL Server’s first significant upgrade in three years features a number of envelope-pushing enhancements and improvements. Which will have the greatest impact on SQL administration and development? More...
Latest Articles

Slowly Changing Dimensions in SQL Server 2005
Audit Data Modifications
SQL Server 2008’s Management Data Warehouse
Same Report but Different Methods in SQL Server Reporting Services ...

More     
 
Latest FAQ's

How to Integrate Performance Monitor and SQL Profiler
SSIS Lookups are Case Sensitive
Convert Number to Words in SSRS
After installing SP2 on SQL Server 2005 x64, when trying to ...

More     
   
Latest Software Reviews

SQL Server DBA Dashboard
SwisSQL DBChangeManager
SQLMesh - SQL Server Search Tool
SoftTreeTech SQL Assistant

More     

How do you display NULL values at the end of a resultset?


Printer friendly

Actually, this question can be extended to: How can you create a custom ORDER BY. But let's first have a look at the following query:

USE PUBS
GO
SELECT
title_id
, type
, price
, royalty
FROM
titles
ORDER BY
royalty

title_id type         price                 royalty
-------- ------------ --------------------- -----------
MC3026   UNDECIDED    NULL                  NULL
PC9999   popular_comp NULL                  NULL
PS1372   psychology   21.5900               10
BU1032   business     19.9900               10
BU1111   business     11.9500               10
BU7832   business     19.9900               10
PS2106   psychology   7.0000                10
PS3333   psychology   19.9900               10
PS7777   psychology   7.9900                10
TC3218   trad_cook    20.9500               10
PC8888   popular_comp 20.0000               10
TC7777   trad_cook    14.9900               10
MC2222   mod_cook     19.9900               12
PS2091   psychology   10.9500               12
TC4203   trad_cook    11.9500               14
PC1035   popular_comp 22.9500               16
MC3021   mod_cook     2.9900                24
BU2075   business     2.9900                24

(18 row(s) affected)

As you can see, the column royalty contains NULL values. Now, someone might be tempted to request that these rows be at the end to the resultset. Probably the easiest way to do this would be to rewrite the query like:

SELECT
title_id
, type
, price
, royalty
FROM
titles
ORDER BY
royalty DESC


Now, those rows are shown at the bottom of the resultset. However, now your aesthetical feeling might be a bit offended, because royalty is shown with the highest value first, and then descending. What now? An easy way is to rewrite the query like:

SELECT
title_id
, type
, price
, royalty
FROM
titles
ORDER BY
CASE WHEN royalty IS NULL THEN 1000 ELSE royalty END


Through the use of the CASE expression, you can filter out the NULL values and assign them the artificial 1000, which is far more than the highest existing royalty to make sure they will move to the end of the resultset. So far, so good. This works, but it isn't a practicable solution, as in most cases you don't know in advance the maximum value of the column you want to sort. To workaround this limitation, you can try:

DECLARE @max_value INT
SELECT @max_value = MAX(royalty)+1 FROM titles
SELECT
title_id
, type
, price
, royalty
FROM
titles
ORDER BY
CASE WHEN royalty IS NULL THEN @max_value ELSE royalty END


This works fine for all cases where you need to sort on a numeric column, but will fail for character columns. And you need an extra query to get the maximum value and increment it by 1. So, this is still not a good generic solution. The best thing you can do here is to create a completely artificial expression in your ORDER BY like this:

SELECT
title_id
, type
, price
, royalty
FROM
titles
ORDER BY
CASE WHEN royalty IS NULL THEN 1 ELSE 0 END
, royalty


We still use a CASE expression, but don't include any column from the underlying table in it. We use a "two-column" ORDER BY. We first assign a 1 for all columns which contain NULL. And 0 to those columns which do not contain NULL. And we order by royalty. This way we get our desired resultset, and our solution doesn't care about the underlying data type of the column we use in the ORDER BY, and the impact on performance is negligible, if there is any at all.



Comments:
Your Name  
Email    
(Emails will not be displayed on the site or used for promotional purposes)
Comment  


Type characters in the image
 
 (case sensitive)

 
 
 







Home | Peformance Articles | Audit Articles | Business Intelligence Articles | Clustering Articles | Developer Articles | Reporting Services Articles | DBA Articles | ASP.NET / ADO.NET Articles | DBA FAQ's | Developer Peformance FAQ's | DBA Peformance FAQ's | Developer FAQ's | Clustering FAQ's | Error Messages | Audit Tool Reviews | Backup Tool Reviews | Coding Tool Reviews | Compare Tool Reviews | Documentation Tool Reviews | Design Tool Reviews | Monitoring Tool Reviews | Log Tool Reviews | Reporting Tool Reviews | Clustering Tool Reviews | Security Tool Reviews | Change Management Tool Reviews | Remote Access Tool Reviews | Book Reviews | Security Tool Reviews | QDPMA Performance Tuning | ADO.NET / ASP.NET | Administration | Analysis/OLAP Services | Application Development | Configuration | Components | ETL | Hardware | High Availability | Hints | Index | Misc | Operating Systems | Performance Tuning | Replication | T-SQL | Views