Mysql 在SQL中覆盖行
所以,我想将键值对的集合存储在数据库中,然后根据一系列集合检索一组组合的键值对。每一套可能都不完整 假设我们有一个如下表:Mysql 在SQL中覆盖行,mysql,sql,oracle,db2,Mysql,Sql,Oracle,Db2,所以,我想将键值对的集合存储在数据库中,然后根据一系列集合检索一组组合的键值对。每一套可能都不完整 假设我们有一个如下表: create table MYTABLE (ROLE VARCHAR(62), KEY VARCHAR(62), VALUE VARCHAR(62)); insert into MYTABLE values('R1', 'K1', 'R1K1'); insert into MYTABLE values('R1', 'K2', 'R1K2'); insert into MYT
create table MYTABLE (ROLE VARCHAR(62), KEY VARCHAR(62), VALUE VARCHAR(62));
insert into MYTABLE values('R1', 'K1', 'R1K1');
insert into MYTABLE values('R1', 'K2', 'R1K2');
insert into MYTABLE values('R1', 'K3', 'R1K3');
insert into MYTABLE values('R2', 'K1', 'R2K1');
insert into MYTABLE values('R2', 'K2', 'R2K2');
insert into MYTABLE values('R2', 'K4', 'R2K4');
insert into MYTABLE values('R3', 'K1', 'R3K1');
insert into MYTABLE values('R3', 'K4', 'R3K4');
insert into MYTABLE values('R3', 'K5', 'R3K5');
insert into MYTABLE values('R4', 'K1', 'R4K1');
insert into MYTABLE values('R5', 'K6', 'R5K6');
当给定序列R1、R2、R3(或R3、R2、R1,具体取决于您的视角)时,我希望得到以下结果:
最初,我打算在SQL之外执行此操作,检索每个集合并将结果转储到散列中,然后让后续项覆盖以前的项:
select KEY,VALUE from MYTABLE where ROLE = 'R1';
select KEY,VALUE from MYTABLE where ROLE = 'R2';
select KEY,VALUE from MYTABLE where ROLE = 'R3';
但是,如果有很多角色可以混合,我不想回到每个角色的数据库
最终我发现这些说法是可行的:
Oracle/DB2:
select distinct KEY, first_value(VALUE) over (partition by KEY order by decode(ROLE, 'R1', 1, 'R2', 2, 'R3', 3) desc) value from MYTABLE where ROLE in ('R1', 'R2', 'R3') order by KEY;
MySQL (guess):
select distinct KEY, first_value(VALUE) over (partition by KEY order by field(ROLE, 'R1, 'R2', 'R3') desc) value from MYTABLE where ROLE in ('R1', 'R2', 'R3') order by KEY;
(结尾的“按键订购”并不是我需要的。)
有更好的方法吗?您可以使用
行号()来表示该逻辑:
这里实际上不需要条件排序,因为'R1'<'R2'<'R3'
。但如果您想对其他序列执行此操作,通常会使用标准的大小写表达式:
select key, value
from (
select t.*,
row_number() over(
partition by key
order by case role when 'R1' then 1 when 'R2' then 2 when 'R3' then 3 end
) as rn
from mytable t
where role in ('R1', 'R2', 'R3')
) t
where rn = 1
这是一种相当可移植的语法,可以在许多Datatabase中使用(只要它们支持窗口函数)。这里有两个更改:1)使用行号()而不是独特的…第一个值(),以及2)使用按大小写排序而不是按解码/字段排序。看起来first_value()在DB2、MySQL、Oracle和SQL Server中很常见(从2012年开始),但“case”显然更具可移植性。也就是说,我想我会做一些解释,看看distinct…first_value()是否比row_number()有任何优势。
select key, value
from (
select t.*,
row_number() over(partition by key order by role) as rn
from mytable t
where role in ('R1', 'R2', 'R3')
) t
where rn = 1
select key, value
from (
select t.*,
row_number() over(
partition by key
order by case role when 'R1' then 1 when 'R2' then 2 when 'R3' then 3 end
) as rn
from mytable t
where role in ('R1', 'R2', 'R3')
) t
where rn = 1