【问题标题】:Oracle group by issue with sql queryOracle 按问题分组 sql 查询
【发布时间】:2020-12-05 07:20:43
【问题描述】:
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

我通过对其他几张表进行某些其他联接得到了这张表,

此表数据表示什么 - 投资组合编号 (123) 在那里,我们总共有三个 AccountNumber。 我们有不同的 LevelCode(这里是 1、2、3),每个级别都被标记到投资组合编号,并且也会标记相同的 3 个帐号。 并且我们在每一行也有状态...已创建跟踪列 jsut 以失败为 1 并通过为 0,我稍后在下面的查询中尝试使用(此列可以删除)

我想找到什么 -

每个唯一投资组合编号的最低级别代码集(包括该集的所有三个accountNumber),其中任一状态失败

查询 - 选择 PortfolioNumber、LevelCode、 min(LevelCode), sum(track) 来自 (我通过其他一些表格获得的表格数据加入..粘贴在上面) 按 PortfolioNumber、LevelCode 分组 总和(轨道)> 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

使用甲骨文

【问题讨论】:

  • 如果你正在寻找它的最小值,为什么要按 levelCode 分组?
  • 按级别代码分组,因为我需要每个 PortfolioNumber 最小级别代码中的所有帐户,这些帐户具有失败状态..因此保持最小..但不确定这种使用方法是否正确
  • 是否存在每个LevelCode 3个AccountNumber都不存在的情况?
  • 不,不会这样
  • 对于 PortfolioNumber = 456 为什么要在结果中包含所有 3 行? LevelCode = 1 是包含 Status = failed 的最小值。

标签: sql oracle11g oracle-sqldeveloper


【解决方案1】:

这个查询:

select distinct PortfolioNumber, 
       min(LevelCode) over (partition by PortfolioNumber) LevelCode
from tablename
group by PortfolioNumber, LevelCode
having sum(track) > 0

返回您想要的 PortfolioNumber/LevelCode 组合。
与操作符IN一起使用来获取表格的行数:

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

【讨论】:

  • 哇,你的速度如此之快和正确......感谢您的帮助,感谢不知道这件事(按 PortfolioNumber 分区)..再次感谢
  • @forpas- 这个小问题我没有提到,如果所有级别代码都通过了特定的 PortfolioNumber (即 sum(track) =0 ),上面我们不会显示投资组合本身..对于这种情况,我想显示该投资组合的最大值(级别代码)..抱歉之前没有提到..尝试在小提琴中更新但没有得到想要的结果..请建议
  • 假设总是首先通过较低级别的代码,然后仅在每个投资组合编号通过较高级别的代码帐户之后...意味着第1级全部通过..第2级有些失败..然后第 3 级有些失败
  • 检查这个:dbfiddle.uk/…
  • 我在我粘贴的查询上方接近它..但是你的查询效果很好..简洁明了..你太棒了:-)
【解决方案2】:

我想我会使用相关子查询:

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) 上的索引轻松优化。

如果您愿意,使用窗口函数的类似方法是:

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

【讨论】:

    猜你喜欢
    • 2011-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多