我有一个表pop,它有3列:idlevelvalue:

CREATE TABLE IF NOT EXISTS `pop` (
  `id` int(6),
  `level` varchar(3),
  `value` int(6),
  PRIMARY KEY (`id`,`level`)
) DEFAULT CHARSET=utf8;
INSERT INTO `pop` (`id`, `level`, `value`) VALUES
  ('1', 'MUN', '243'),
  ('1', 'CAN', '335'),
  ('1', 'PRO', '345'),
  ('2', 'DIS', '345'),
  ('2', 'MUN', '243'),
  ('3', 'DIS', '335');

大约有1000万个ID,只有4个级别.所有id都至少有1个级别.级别可以是"有序的",即使它们是字符串:("diss"<"mun"<"can"<"pro").

我想实现的目标是:

  • 对于每个id,请给我可能的最低级别及其值.

因此,预期输出为:

  1,'MUN',243
  2,'DIS',345
  3,'DIS',335

我试过了

SELECT id,
CASE 
when level = 'DIS' THEN level
when level = 'MUN' THEN level 
when level = 'CAN' THEN level
when level = 'PRO' THEN level
END as level,
value FROM `pop` order by id, level

但它不起作用,它返回整个表.

有什么主意吗?

(顺便说一句,我在AWS Athena中使用SQL)

推荐答案

您可以将row_number函数与ORDER BY子句中的CASE表达式一起使用,以指定级别的顺序,如下所示:

select id, level, value
from
(
  select *,
    row_number() over (partition by id 
          order by 
             case level 
                 when 'DIS' then 1 
                 when 'MUN' then 2 
                 when 'CAN' then 3 
                 when 'PRO' then 4 
              end) rn
  from pop
) t
where rn = 1

demo

Sql相关问答推荐

使用自动增量ID插入失败(无法将值空插入列ID)

SQL(PostgreSQL)从条件创建点表

不可能在SQL MERGE子句中引发异常

基于多个字段删除Access中的重复记录,同时保留最低优先级

Access VBA SQL命令INSERT FOR MULTIME VALUE

SQL:如何取上一年的平均值?

在SQL中为两个日期之间的每个日期添加行

需要从键-值对数据中提取值

按用户和时间列出的SQL Group考勤列表

在 postgres 中插入或更新 jsonb 数组的对象

复制行并根据 Oracle SQL 中其他表的值更改值

JSON对象查询SQL服务器

Postgres如何在一个日历周中前进和回填值

多行状态下的分组查询判断状态

我需要遍历权重值表并确定每个权重是否有效

如何对 SQL 表中的连续时间戳进行分组?

以 15 分钟为间隔的使用情况SQL 查询

在 MS Access 中连接相关记录

使用 SAVE TRANSACTION 时 BEGIN 和 COMMIT 语句的数量不匹配

从 Pyspark 转换为具有多个分组条件的语句时的情况