Skip to content

Instantly share code, notes, and snippets.

@sinairv
Created August 6, 2012 06:45
Show Gist options
  • Save sinairv/3271660 to your computer and use it in GitHub Desktop.
Save sinairv/3271660 to your computer and use it in GitHub Desktop.
Returning 2 distinct columns from a 3-column result-set
-- We want to return one phone number per each person-id
-- If a phone number is flagged as default it has a higher priority
-- There may be more than one phone numbers be marked as default,
-- or one person may have several phone numbers none of which is marked as default
-- Table Definition
CREATE TABLE [dbo].[PersonPhone](
[PersonId] [int] NOT NULL,
[Phone] [varchar](50) NOT NULL,
[IsDefault] [bit] NOT NULL
)
GO
-- Tab-separated sample data
--
--PersonId Phone IsDefault
--1 123 True
--1 234 False
--1 324 False
--2 1234 False
--2 23234 False
--3 23948 True
--3 213432 False
--3 9328 False
--4 29343 False
--4 492384 False
--5 93432 True
--5 3984 True
--5 821433 False
--6 23943 False
--6 237423 False
--6 324234 True
--6 233434 False
-- solution 1
SELECT Ph.PersonId,
(
SELECT TOP 1 Ph2.Phone FROM PersonPhone Ph2
WHERE Ph2.PersonId = Ph.PersonId
ORDER BY Ph2.IsDefault DESC
) AS Phone
FROM PersonPhone Ph
GROUP BY Ph.PersonId
GO
-- Solution 2
SELECT Ph.PersonId, Ph.IsDefault, MAX(Ph.Phone)
FROM PersonPhone Ph
INNER JOIN
(
SELECT Ph2.PersonId, MAX(CONVERT(INT, Ph2.IsDefault)) AS MaxDef
FROM PersonPhone Ph2
GROUP BY Ph2.PersonId
) T
ON Ph.PersonId = T.PersonId AND Ph.IsDefault = T.MaxDef
GROUP BY Ph.PersonId, Ph.IsDefault
GO
-- TODO: Which of them is better and why?
-- Turning on Client Statistics on SQL Server Express 2012 on both above queries,
-- reveal that the first solution is less efficient on processing and waiting time
-- compared to the second one. Conversely, the first query is more efficient in
-- terms of the number of bytes received and sent.
-- However the first solution is much easier to write for a programmer. Imagine for
-- a second that what would happen if we wanted to have 3 or 4 distinct columns in
-- a result set and how would that be implemented using the second query.
-- A definitely WRONG answer
SELECT Ph.PersonId, MAX(CONVERT(INT, Ph.IsDefault)), MAX(Ph.Phone)
FROM PersonPhone Ph
GROUP BY Ph.PersonId
GO
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment