Oracle 按 sql 查询的问题分组
Oracle group by issue with sql query
PortfolioNumber LevelCode AccountNumber Status track
123 2 A101 Failed 1
123 2 A102 Failed 1
123 2 A103 Passed 0
123 1 A101 Passed 0
123 1 A102 Passed 0
123 1 A103 Passed 0
123 3 A101 Failed 1
123 3 A102 Failed 1
123 3 A103 Failed 1
456 1 A406 Failed 1
456 1 A407 Passed 0
456 1 A408 Failed 1
我通过对其他几个 table 进行某些其他连接得到了这个 table,
此 table 数据表示什么 -
Portflio Number (123) 在那里,我们总共有三个 AccountNumber。
我们有不同的 LevelCode(此处为 1、2、3),每个级别都标记为 portfolioNumber,并且也会标记相同的 3 个帐号。
并且我们在每一行都有状态...已经创建了跟踪列 jsut 失败为 1,通过为 0,我稍后在下面的查询中尝试使用(此列可以删除)
我要查找的内容 -
每个唯一投资组合编号(包括该组的所有三个帐户编号)的最低级别代码集,其中任何一个状态失败
查询 - Select PortfolioNumber, LevelCode,
min(LevelCode), sum(track) 来自
(table 数据是我通过其他 tables 连接获得的..粘贴在上面)
按 PortfolioNumber, LevelCode 分组
有 sum(track) > 0'
但这并没有给出正确的结果和所有列,运行现在没有选项
我想要的结果
PortfolioNumber LevelCode AccountNumber Status track
123 2 A101 Failed 1
123 2 A102 Failed 1
123 2 A103 Passed 0
456 1 A406 Failed 1
456 1 A407 Passed 0
456 1 A408 Failed 1
使用甲骨文
这个查询:
select distinct PortfolioNumber,
min(LevelCode) over (partition by PortfolioNumber) LevelCode
from tablename
group by PortfolioNumber, LevelCode
having sum(track) > 0
returns 您想要的 PortfolioNumber/LevelCode 组合。
将它与运算符 IN
一起使用以获取 table:
的行
select *
from tablename
where (PortfolioNumber, LevelCode) in (
select distinct PortfolioNumber,
min(LevelCode) over (partition by PortfolioNumber) LevelCode
from tablename
group by PortfolioNumber, LevelCode
having sum(track) > 0
)
参见demo。
结果:
> PORTFOLIONUMBER | LEVELCODE | ACCOUNTNUMBER | STATUS | TRACK
> --------------: | --------: | :------------ | :----- | ----:
> 123 | 2 | A101 | Failed | 1
> 123 | 2 | A102 | Failed | 1
> 123 | 2 | A103 | Passed | 0
> 456 | 1 | A406 | Failed | 1
> 456 | 1 | A407 | Passed | 0
> 456 | 1 | A408 | Failed | 1
我想我会使用相关子查询:
select t.*
from t
where t.levelcode = (select min(t2.levelcode)
from t t2
where t2.portfolionumber = t.portfolionumber and
t2.status = 'Failed'
);
这似乎是最简单的解决方案,可以使用 (portfolionumber, status, levelcode)
上的索引轻松优化。
如果您愿意,使用 window 函数的类似方法是:
select t.*
from (select t.*,
min(case when status = 'failed' then levelcode end) over (partition by portfolionumber) as min_failed_levelcode
from t
) t
where levelcode = min_failed_levelcode
PortfolioNumber LevelCode AccountNumber Status track
123 2 A101 Failed 1
123 2 A102 Failed 1
123 2 A103 Passed 0
123 1 A101 Passed 0
123 1 A102 Passed 0
123 1 A103 Passed 0
123 3 A101 Failed 1
123 3 A102 Failed 1
123 3 A103 Failed 1
456 1 A406 Failed 1
456 1 A407 Passed 0
456 1 A408 Failed 1
我通过对其他几个 table 进行某些其他连接得到了这个 table,
此 table 数据表示什么 - Portflio Number (123) 在那里,我们总共有三个 AccountNumber。 我们有不同的 LevelCode(此处为 1、2、3),每个级别都标记为 portfolioNumber,并且也会标记相同的 3 个帐号。 并且我们在每一行都有状态...已经创建了跟踪列 jsut 失败为 1,通过为 0,我稍后在下面的查询中尝试使用(此列可以删除)
我要查找的内容 -
每个唯一投资组合编号(包括该组的所有三个帐户编号)的最低级别代码集,其中任何一个状态失败
查询 - Select PortfolioNumber, LevelCode, min(LevelCode), sum(track) 来自 (table 数据是我通过其他 tables 连接获得的..粘贴在上面) 按 PortfolioNumber, LevelCode 分组 有 sum(track) > 0'
但这并没有给出正确的结果和所有列,运行现在没有选项
我想要的结果
PortfolioNumber LevelCode AccountNumber Status track
123 2 A101 Failed 1
123 2 A102 Failed 1
123 2 A103 Passed 0
456 1 A406 Failed 1
456 1 A407 Passed 0
456 1 A408 Failed 1
使用甲骨文
这个查询:
select distinct PortfolioNumber,
min(LevelCode) over (partition by PortfolioNumber) LevelCode
from tablename
group by PortfolioNumber, LevelCode
having sum(track) > 0
returns 您想要的 PortfolioNumber/LevelCode 组合。
将它与运算符 IN
一起使用以获取 table:
select *
from tablename
where (PortfolioNumber, LevelCode) in (
select distinct PortfolioNumber,
min(LevelCode) over (partition by PortfolioNumber) LevelCode
from tablename
group by PortfolioNumber, LevelCode
having sum(track) > 0
)
参见demo。
结果:
> PORTFOLIONUMBER | LEVELCODE | ACCOUNTNUMBER | STATUS | TRACK
> --------------: | --------: | :------------ | :----- | ----:
> 123 | 2 | A101 | Failed | 1
> 123 | 2 | A102 | Failed | 1
> 123 | 2 | A103 | Passed | 0
> 456 | 1 | A406 | Failed | 1
> 456 | 1 | A407 | Passed | 0
> 456 | 1 | A408 | Failed | 1
我想我会使用相关子查询:
select t.*
from t
where t.levelcode = (select min(t2.levelcode)
from t t2
where t2.portfolionumber = t.portfolionumber and
t2.status = 'Failed'
);
这似乎是最简单的解决方案,可以使用 (portfolionumber, status, levelcode)
上的索引轻松优化。
如果您愿意,使用 window 函数的类似方法是:
select t.*
from (select t.*,
min(case when status = 'failed' then levelcode end) over (partition by portfolionumber) as min_failed_levelcode
from t
) t
where levelcode = min_failed_levelcode