Reputation: 55
Apologies if the title is confusing, i'm finding it hard to put into words exactly what i'm looking for. If someone can point me in the correct direction or if another question exists, letting me know would be much appreciated.
If I have the following values in a table I wish to write a query that selects a single record for each [ContactID]
.
The query should check first if a record exists with [PhoneType]
'Mob' then --> 'Work' then --> 'Hom' and return the first record that matches and ignore the other records for the [ContactID]
CREATE TABLE #Test
(
[ContactID] int,
[PhoneNo] NVARCHAR(20),
[PhoneType] NVARCHAR(20)
);
INSERT INTO #Test
(
[ContactID],
[PhoneNo],
[PhoneType]
)
VALUES
(1, '51351301', 'Mob'),
(1, '999', 'Work'),
(1, '8461', 'Hom'),
(2, '213231321', 'Work'),
(3, '848136', 'Mob'),
(4, '23231', 'Hom'),
(4, '2132315', 'Work')
The result would look like
(1, '51351301', 'Mob'),
(2, '213231321', 'Work'),
(3, '848136', 'Mob'),
(4, '2132315', 'Work')
Upvotes: 1
Views: 1335
Reputation: 3591
I think this will do what you want. It sets a row ID for each ContactID
, and only pulls the first one for each ContactID
CREATE TABLE #Test
(
[ContactID] int,
[PhoneNo] NVARCHAR(20),
[PhoneType] NVARCHAR(20)
);
--DROP TABLE #Test
INSERT INTO #Test
(
[ContactID],
[PhoneNo],
[PhoneType]
)
VALUES
(1, '51351301', 'Mob'),
(1, '999', 'Work'),
(1, '8461', 'Hom'),
(2, '213231321', 'Work'),
(3, '848136', 'Mob'),
(4, '23231', 'Hom'),
(5, '2132315', 'Work')
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER(PARTITION BY ContactID ORDER BY PhoneType ASC) AS RowNum
FROM #Test
WHERE PhoneType IN ('Mob', 'Work', 'Hom')
) Sub
WHERE RowNum = 1
If you want to get specific phone type first you can use this select statement for ronum
SELECT *, ROW_NUMBER() OVER(PARTITION BY ContactID ORDER BY CASE WHEN PhoneType = 'Mob' THEN 1 WHEN PhoneType = 'Work' THEN 2 WHEN PhoneType = 'Hom' THEN 3 END ASC) AS RowNum
FROM #Test
WHERE PhoneType IN ('Mob', 'Work', 'Hom')
Upvotes: 2
Reputation: 6193
Use window function
with top(1) with ties
Try this:
SELECT *
FROM(
SELECT TOP(1) WITH ties *
FROM #Test t
ORDER BY ROW_NUMBER() OVER (PARTITION BY contactid
ORDER BY (CASE WHEN phoneType = 'Mob' THEN 1
WHEN phoneType = 'Work' THEN 2
WHEN phoneType = 'Hom' THEN 3
ELSE 4
END)
)
)D
ORDER BY D.ContactID
Upvotes: 3
Reputation: 1269633
You can use row_number()
:
select t.*
from (select t.*,
row_number() over (partition by contactid
order by (case when phoneType = 'Mob' then 1
when phoneType = 'Work' then 2
when phoneType = 'Hom' then 3
else 4
end)
) as seqnum
from #test t
) t
where seqnum = 1;
If you have a separate table with contacts, you can also use apply
:
select t.*
from contacts c cross apply
(select top (1) t.*
from #test t
where c.contactid = t.contactid
order by charindex(phonetype, 'Mob,Work,Hom')
) t;
Note that this uses a shorthand for the ordering. This will work for your phone types -- but assumes these are the only three.
Upvotes: 2