我有一个Table1
如下:
Account Name Flagged
------- ---- -------
001 John 0
001 Jacob 0
002 Austin 0
002 Ashley 1
003 Mary 1
003 Megan 1
这是我试图弄清楚的简化版本。基本上我有一组帐户ID,如果需要,每个帐户ID基本上可以附加无限数量的名称。有些将有 1 个名称,有些将有 1000 个名称。每个名称都标记为 0 或 1。
对于每个帐户,我希望:
- 如果所有行都已标记 = 0,则选择所有行
- 如果所有行都已标记 = 1,则选择所有行
- 如果行具有混合标志,则仅选择标记 = 0 的行。 即有些是 0 有些是 1
对于这张小桌子,我希望它返回
Account Name Flagged
------- ---- -------
001 John 0
001 Jacob 0
002 Austin 0
003 Mary 1
003 Megan 1
登的解决方案是正确的。但是,您也可以使用 MIN
窗口函数获取每个帐户的最小标志(假设 flagged 只有值 0 和 1(并仅获取这些行。
select account,name,flagged
from (select t.*,min(flagged) over(partition by account) as min_flag
from tablename t
) x
where flagged=min_flag
这是优先级查询的一种形式。 我认为最简单的方法是not exists
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
);
这个想法很简单:选择标志为 0 的所有行。 然后,仅当没有相应的零行时,才选择标志为 1 的所有行。
有几种方法可以返回指定的结果。
下面是一种方法的示例,它使用 NOT EXISTS 谓词和相关子查询:
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
下面是使用联接到内联视图的方法示例:
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
编辑:原始示例使用MySQL语法;查询经过修订,因此语法与SQL Server兼容。