如何在不分组的情况下获取一列的最小值并获取另一列?

How to get the minimum of one column and get another column without grouping?

我正在尝试从 table 中获取具有特定列的最小值的记录,但我想要该记录中的其余数据而不对其中一列进行分组。

这是示例数据:

我想要一个查询 return:

January, 24, 0, 3
February, 12, 0, 1

一种选择是使用对数据进行“排序”的分析函数;然后获取排名为 最高 的行。像这样:

示例数据:

SQL> with test (month, day, c_initial, ending) as
  2    (select 'jan', 24, 0, 3 from dual union all
  3     select 'jan', 24, 1, 6 from dual union all
  4     select 'jan', 24, 2, 2 from dual union all
  5     select 'feb', 12, 0, 1 from dual union all
  6     select 'feb', 12, 1, 6 from dual union all
  7     select 'feb', 12, 2, 5 from dual
  8    ),

查询从这里开始:

  9  temp as
 10    (select t.*,
 11       row_number() over (partition by month, day order by c_initial) rn
 12     from test t
 13    )
 14  select month, day, c_initial, ending
 15  from temp
 16  where rn = 1;

MON        DAY  C_INITIAL     ENDING
--- ---------- ---------- ----------
feb         12          0          1
jan         24          0          3

SQL>

如果有平局,则考虑RANK

此外,initial 是无效的列名,因此我将其重命名为 c_initial

@Littlefoot 给出了可能唯一合理的答案。但是,如果您的 table 非常大并且性能有问题,则此版本可能更高效:

select    month, 
          day, 
          min(c_initial) keep ( dense_rank first order by c_initial asc ) c_initial,
          min(ending) keep ( dense_rank first order by c_initial asc ) ending
from      your_table
group by  month, day; 

min() keep 告诉 Oracle 您只需要每个组中任何行的值具有 c_initial 的最低值。因此,它可以丢弃它知道您不感兴趣的值,而不是保留它们,对它们进行排序,然后给您第一个。

顺便说一句,告诉 Oracle return 具有最低 c_initial 值的行的数据是 dense_rank first order by c_initial asc 子句而不是 min() 功能。使用 max() 函数会给出完全相同的答案。我使用 min() 只是一种风格——它提醒我我正在寻找组中的第一行。