Reputation: 13
Ello!
I'm trying to select a single row with either 'w', 'e' or 's' and an unique GUID. 'e' has a the highest priority so when a GUID contains that that line should be selected. 'w' the 2nd highest priority, so when there is no other than 's' 'w' should be selected. Along with the entire row data.
I've tried to use the following code:
SELECT * FROM TABLENAME
WHERE GUID IN (SELECT DISTINCT GUID FROM TABLENAME )
AND (CATEGORY='S' OR CATEGORY='E' OR CATEGORY='W')
Is there anyway how I can do what I'm describing? I've been trying to use different ways of using distinct and other methods but it's still giving me more than one line per GUID.
Group by hasn't worked either. Since I get an error when I add that.
EDIT: Added Images https://i.sstatic.net/3zgeF.png
Upvotes: 1
Views: 2447
Reputation: 49260
select guid, min(priority) from
(SELECT *,
case when category = 'E' then 1
when category = 'W' then 2
when category = 'S' then 3
end as priority
FROM TABLENAME
WHERE CATEGORY in ('S','E','W') ) a
The inner query assigns priority to the category
column as per the question. In the outer query you select from whichever category has the highest priority. Also include all the other columns you need in the outer select
.
Edit: The method above isn't robust as you can't use the calculated priority
column to select the corresponding category per guid.
Hence, Another approach is to use union
.
SELECT * FROM TABLENAME
WHERE CATEGORY = 'E'
union
SELECT * FROM TABLENAME
WHERE CATEGORY = 'W'
and guid not in (select guid from tablename where category ='E')
union
SELECT * FROM TABLENAME
WHERE CATEGORY = 'S'
and guid not in(select guid from tablename where category in ('E','W'))
The first query selects all rows where category is E
. The second query selects all rows whose category is W
and whose guid wasn't selected before. The third query selects all rows whose category is S
and whose guid wasn't selected in the previous two queries.
UNION
ing all the queries should give you the results you need.
Try the SQL fiddle with dummy data. http://sqlfiddle.com/#!9/07c0d/1
Upvotes: 3
Reputation: 1269563
One method is to get the appropriate category for each guid and then join
back. Another is a series of union all
s. The latter is possibly more efficient, because you don't have very many options to prioritize:
select t.*
from tablename t
where category = 'e'
union all
select t.*
from tablename t
where category = 'w' and
not exists (select 1 from tablename t2
where t2.category in ('e') and t2.guid = t.guid
)
union all
select t.*
from tablename t
where category = 's' and
not exists (select 1 from tablename t2
where t2.category in ('e', 'w') and t2.guid = t.guid
) ;
For performance, you want an index on category
and guid, category
.
Upvotes: 0