Reputation: 12113
If someone could update the title to better reflect my question that would be much appreciated. I think I've struggled to find the answer somewhat because I don't know the right search terms.
If I have the following values in a table:
TableID TableSensitivity ----------------------------- 1 aSensitivity 1 aRevision 2 bRevision 3 cRevision 3 cSensitivity
How can I filter the values containing "Revision" only for each TableID where the is already a value containing "Sensitivity". This is the expected output:
TableID TableSensitivity ----------------------------- 1 aSensitivity 2 bRevision 3 cSensitivity
Here's an example setup:
DECLARE @Example TABLE (TableID INT, TableSensitivity VARCHAR(200))
INSERT INTO @Example(TableID, TableSensitivity) VALUES (1, 'aSensitivity')
INSERT INTO @Example(TableID, TableSensitivity) VALUES (1, 'aRevision')
INSERT INTO @Example(TableID, TableSensitivity) VALUES (2, 'bRevision')
INSERT INTO @Example(TableID, TableSensitivity) VALUES (3, 'cSensitivity')
INSERT INTO @Example(TableID, TableSensitivity) VALUES (3, 'cRevision')
I've tried using CASE to determine the rows with sensitivities and figured that I could use a MAX to filter, but couldn't get it working:
SELECT TableID
, TableSensitivity
, CASE WHEN TableSensitivity LIKE '%Sensitivity' THEN 1 ELSE 0 END 'SomeKey'
FROM @Example
Upvotes: 3
Views: 114
Reputation: 1269773
Originally, I completely misunderstood the question. I see, you want a prioritization query. One simple method is:
select e.*
from @example e
where e.TableSensitivity like '%Sensitivity'
union all
select e.*
from @example e
where e.TableSensitivity like '%Revision' and
not exists (select 1
from @example e2
where e2.tableId = e.tableId and
e2.TableSensitivity like '%Sensitivity'
);
A more general approach uses row_number()
:
select e.*
from (select e.*,
row_number() over (partition by tableId
order by case when e.TableSensitivity like '%Sensitivity' then 1 when e.TableSensitivity like '% Revision' then 2 else 3 end
) as seqnum
from @example e
) e
where seqnum = 1;
Upvotes: 0
Reputation: 2907
This can also be achieved using the FIRST_VALUE function (for SQL Server 2012 and over)
SELECT DISTINCT
TableID,
FIRST_VALUE(TableSensitivity) OVER (PARTITION BY TableID ORDER BY
CASE WHEN TableSensitivity LIKE '%Sensitivity' THEN 1
WHEN TableSensitivity LIKE '%Revision' THEN 2
ELSE 3 END) as TableSensitivity
FROM @Example
Upvotes: 1
Reputation: 101
this gets rid of the rows in @Example
and returns your expected result. it can be modified and worked into your query if needed:
DELETE
FROM @Example
WHERE TableID IN
(
SELECT TableID
FROM @Example
WHERE TableSensitivity LIKE '%Sensitivity%'
)
AND TableSensitivity LIKE '%Revision%'
SELECT *
FROM @Example
Upvotes: 2
Reputation: 1081
You could use a WHERE NOT EXISTS
SELECT TableID
, TableSensitivity
FROM @Example e1
WHERE NOT EXISTS
(
SELECT *
FROM @Example e2
WHERE e1.TableID=e2.TableID
AND e2.TableSensitivity LIKE '%Sensitivity'
AND e1.TableSensitivity LIKE '%Revision'
)
Upvotes: 3