Reputation: 49
I have a Table1
as follows:
Account Name Flagged
------- ---- -------
001 John 0
001 Jacob 0
002 Austin 0
002 Ashley 1
003 Mary 1
003 Megan 1
This is a simplied version of what I'm trying to figure out. Basically I have a set of Account IDs, each account ID can have basically an infinite number of names attached if it wanted. Some will have 1 name, some will have 1000 names. Each name is flagged 0 or 1.
For each account, I want to:
For this little table, I'd want it to return
Account Name Flagged
------- ---- -------
001 John 0
001 Jacob 0
002 Austin 0
003 Mary 1
003 Megan 1
Upvotes: 0
Views: 384
Reputation: 108460
There are several ways to return the specified result.
Here's an example of one approach, using a NOT EXISTS predicate and a correlated subquery:
SELECT t.account
, t.name
, t.flagged
FROM [Table1] t
WHERE t.flagged = 0
OR ( t.flagged = 1 AND NOT EXISTS
( SELECT 1
FROM [Table1] f
WHERE f.account = t.account
AND f.flagged = 0
)
)
ORDER BY t.account, t.name, t.flagged
Here's an example of an approach using a join to an inline view:
SELECT t.account
, t.name
, t.flagged
FROM ( SELECT n.account
, MIN(n.flagged) AS mf
FROM [Table1] n
WHERE n.flagged IN (0,1)
GROUP BY n.account
) s
JOIN [Table1] t
ON t.account = s.account
AND t.flagged = s.mf
ORDER BY t.account, t.name, t.flagged
EDIT: Original examples were using MySQL syntax; queries revised so syntax is compatible with SQL Server.
Upvotes: 0
Reputation: 49260
Gordon's solution is correct. However, you can also use MIN
window function to get the minimum flag per account (assuming flagged has values 0 and 1 only) and get only those rows.
select account,name,flagged
from (select t.*,min(flagged) over(partition by account) as min_flag
from tablename t
) x
where flagged=min_flag
Upvotes: 3
Reputation: 1270401
This is a form of prioritization query. I think the simplest approach is not exists
with union all
:
select t1.*
from table1 t1
where t1.flagged = 0
union all
select t1.*
from table1 t1
where t1.flagged = 1 and
not exists (select 1
from table1 tt1
where tt1.account = t1.account and tt1.flagged = 0
);
The idea is simple: select all rows with a flag of 0. Then select all rows that have a flag of 1, only if there are no corresponding rows with a zero.
Upvotes: 2