COALESCE() accepts a series of values and a value to use in the event that all items in the list are null; then, it returns the first not-null value. This tip describes two creative uses of the COALESCE() function in SQL Server.

Here is a simple example: You have a table of persons whose columns include FirstName, MiddleName and LastName. The table contains these values:

  • John A. MacDonald
  • Franklin D. Roosevelt
  • Madonna
  • Cher
  • Mary Weilage

If you want to print their complete names as single strings, here's how to do it with COALESCE():

SELECT FirstName + ' ' +COALESCE(MiddleName,'')+ ' ' +COALESCE(LastName,'')

If you don't want to write that for every query, the code below shows how you can turn it into a function.

CREATE FUNCTION WholeName
(
      -- Add the parameters for the function here
      @first varchar(50),
      @middle varchar(50),
      @last varchar(50)
)
RETURNS varchar(50)
AS
BEGIN
      -- Declare the return variable here
      DECLARE @Result varchar(50)
      -- Add the T-SQL statements to compute the return value here
      SELECT @Result = @first +' '+COALESCE(@middle,'')+' '+COALESCE(@last,'')
      -- Return the result of the function
      RETURN @Result
END
GO

Now whenever you need this script (regardless of what the columns are actually named) just call the function and pass the three columns. In the examples below, I'm passing literals, but you can substitute column names and achieve the same results:

SELECT dbo.WholeName('James',NULL,'Bond')
UNION
SELECT dbo.WholeName('Cher',NULL,NULL)
UNION
SELECT dbo.WholeName('John','F.','Kennedy')

Here is the result set:

Cher  
James  Bond
John F. Kennedy

You'll notice a hole in our thinking -- there are two spaces in James Bond's name. It's easy to fix this by changing the @result line to the following:

SELECT @Result = LTRIM(@first + ' ' + COALESCE(@middle,'') + ' ') + COALESCE(@last,'')

Here's another use of COALESCE(). In this example, I will produce a list of monies paid to employees. The problem is there are different payment arrangements for different employees (e.g., some employees are paid by the hour, by piece work, with a weekly salary, or by commission).

Here is the code to create a sample table:

CREATE TABLE [Coalesce_Demo].[PayDay](
      [EmployeeID] [int] NOTNULL,
      [HourlyWage] [money] NULL,
      [HoursPerWeek] [int] NULL,
      [AmountPerPiece] [money] NULL,
      [PiecesThisWeek] [int] NULL,
      [WeeklySalary] [money] NULL,
      [CommissionThisWeek] [int] NULL,
 CONSTRAINT [PK_PayDay] PRIMARYKEYCLUSTERED
(
      [EmployeeID] ASC
)WITH(PAD_INDEX  =OFF,STATISTICS_NORECOMPUTE  =OFF,IGNORE_DUP_KEY=OFF,ALLOW_ROW_LOCKS  =ON,ALLOW_PAGE_LOCKS  =ON)ON [PRIMARY]
)ON [PRIMARY]

Here are a few sample rows, one of each type:

1     18.0040    NULL  NULL  NULL  NULL
2     NULL  NULL  4.00  400   NULL  NULL
3     NULL  NULL  NULL  NULL  800.00      NULL
4     NULL  NULL  NULL  NULL  500.00      600

Use the following code to list the amount paid to employees (regardless of how they are paid) in a single column:

SELECT
      EmployeeID,
      COALESCE(HourlyWage * HoursPerWeek,0)+
      COALESCE(AmountPerPiece * PiecesThisWeek,0)+
      COALESCE(WeeklySalary + CommissionThisWeek,0)AS Payment
FROM [Coalesce_Demo].[PayDay]

Here is the result set:

EmployeeID  Payment
1     720.00
2     1600.00
3     800.00
4     1100.00

You might need that expression in several places in your application and, although it works, it isn't very graceful. This is how you can create a calculated column to do it:

ALTER TABLE Coalesce_Demo.PayDay
ADD Payment AS
      COALESCE(HourlyWage * HoursPerWeek,0)+
      COALESCE(AmountPerPiece * PiecesThisWeek,0)+
      COALESCE(WeeklySalary + CommissionThisWeek,0)

Now a simple SELECT * displays the pre-calculated results.

Summary

This tip demonstrates some unusual ways and places to apply the power of COALESCE(). In my experience, COALESCE() most often appears within a very specific content, such as in a query or view or stored procedure.

You can generalise the use of COALESCE() by placing it in a function. You can also optimise its performance and make its results constantly available by placing it in a calculated column.

Database Jumping This was published in Database Jumping, check every Thursday for more stories

Related links

Comments

1

Your name - 10/03/08

Stay on topic (policy).No HTML tags.

» Report offensive content

2

Chris Preece - 19/03/08

Thanks for this, some good ideas here.

Coalesce is also useful for producing a CSV list.

I used the following SQL to produce a CSV of Courses associated with any given user:

select @list = coalesce(@list + ',','')+cast(Course_ID as varchar(6)) FROM Users_T WHERE (User_ID = @UID)

» Report offensive content

3

Chris Preece - 19/03/08

select @list = coalesce(@list + ',','')+cast(Course_ID as varchar(6)) FROM Users_CourseLink_T WHERE (User_ID = @UID)

» Report offensive content

Leave a comment

You must read and type the 6 chars within 0..9 and A..F

* indicates mandatory fields.

3

Chris Preece - 19/03/08

select @list = coalesce(@list + ',','')+cast(Course_ID as varchar(6)) FROM Users_CourseLink_T WHERE (User_ID = @UID) ... more

2

Chris Preece - 19/03/08

Thanks for this, some good ideas here. Coalesce is also useful for producing a CSV list. I used the following SQL to produce ... more

1

Your name - 03/10/08

Stay on topic (policy).No HTML tags. ... more

Log in


Sign up | Forgot your password?

What's on?

  • Optus Deal

    Broadband + home phone + PlayStation®3 in a single package price!