【问题标题】:Select column not on a group by statement选择不在 group by 语句上的列
【发布时间】:2021-11-17 05:33:26
【问题描述】:

所以,我有一个名为 RACES 的表,其中包含以下列

raceid | year | round

我想获得每年最后一场比赛的raceid,这将在每年的圆形栏中具有最高值。所以我做了以下查询:

SELECT
    year,
    max(round)
FROM races
group by year
order by year;

结果是:

year    max(round)
1950    7
1951    8
1952    8
1953    9
1954    9

如果我这样做了

SELECT * FROM RACES WHERE YEAR = 1950;

我明白了:

raceid  year    round
833     1950    1
834     1950    2
835     1950    3
836     1950    4
837     1950    5
838     1950    6
839     1950    7

由于轮数随时间变化,1951 年可能不是 7 轮而是 10 轮。所以我希望始终获得特定年份的轮数最大值,然后将其与相应的 raceid 一起打印圆形的。在这种情况下,它将是 839

由于raceid 不在group by 中,我无法在第一个查询中选择它。我该怎么做?

【问题讨论】:

  • 能否也指定预期的结果。

标签: sql oracle group-by max


【解决方案1】:

使用您发布的示例数据,这只是另一个 MAX 函数调用:

SQL> with races (raceid, year, round) as
  2    (select 700, 1940, 1 from dual union all
  3     select 701, 1940, 2 from dual union all
  4     --
  5     select 833, 1950, 1 from dual union all
  6     select 838, 1950, 6 from dual union all
  7     select 839, 1950, 7 from dual
  8    )
  9  select year,
 10        max(round) max_round,
 11        max(raceid) max_raceid
 12  from races
 13  group by year;

      YEAR  MAX_ROUND MAX_RACEID
---------- ---------- ----------
      1940          2        701
      1950          7        839

SQL>

但是,如果 RACEID 不是 MAXROUND,那么您可以将当前查询用作子查询(或 CTE)并将其与“原始”表连接:

SQL> with races (raceid, year, round) as
  2    (select 700, 1940, 1 from dual union all
  3     select 701, 1940, 2 from dual union all
  4     --
  5     select 900, 1950, 1 from dual union all  --> 900 is MAX for year 1950
  6     select 838, 1950, 6 from dual union all
  7     select 839, 1950, 7 from dual
  8    ),
  9  mrid as
 10    (select year,
 11            max(round) max_round
 12     from races
 13     group by year
 14    )
 15  select m.year,
 16         m.max_round,
 17         r.raceid
 18  from mrid m join races r on r.year = m.year and r.round = m.max_round;

      YEAR  MAX_ROUND     RACEID
---------- ---------- ----------
      1940          2        701
      1950          7        839

SQL>

【讨论】:

  • 既然我的数据已经在比赛表中,我是否可以在不需要使用 te WITH 函数传递这些值的情况下这样做?
  • @BrenoJones - WITH 是查询中的“子句”(不是“函数”)。在此处使用的 Littlefoot 等情况下,我们经常将测试数据放在 WITH 子句中,作为子查询,因此我们不需要在数据库中创建实际表。 WITH 子句不是答案的一部分 - 它只是为了方便起见,因此可以临时测试查询。删除它,并在查询的其余部分使用实际的表名和列名。
【解决方案2】:
select year, max(round) as max_round, 
       max(raceid) keep (dense_rank last order by round) as raceid
from   races
group  by year
order  by year
;

firstlast 函数的文档:

https://docs.oracle.com/database/121/SQLRF/functions074.htm#SQLRF00641

【讨论】:

    猜你喜欢
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-19
    • 2011-06-14
    • 2019-12-22
    • 2020-01-01
    • 1970-01-01
    相关资源
    最近更新 更多