如何从以下位置转换表:
drop table if exists simon;
Create table simon (userId int, passageId int, score int);
INSERT INTO simon (userId, passageId, score )
VALUES
(10, 1, 2),
(10, 1, 3),
(10, 2, 1),
(10, 2, 3),
(10, 2, 5),
(11, 1, 1),
(11, 2, 2),
(11, 2, 3),
(11, 3, 4);
要:
userId passageId score1 score2
10 1 2 3
10 2 1 3
11 1 1 null
11 2 2 3
11 3 4 null
请注意,仅保留前两个分数,因此忽略(10,2,5)。 我正在使用sql在mySQL数据库中工作。
答案 0 :(得分:0)
首先,您应定义订单以获取值。对于每个userId
和passageId
,即2个最小分数或2个最高分数。
以下查询将为每对(userId,passageId)
获取2个最小分数,并将其分别作为simon2
和score1
存储在表score2
中
Create table simon2 (
userId int, passageId int,
score1 int,score2 int);
insert into simon2(userId,passageId,score1,score2)
select
t1.userId,t1.passageId,t1.s1,
(select min(distinct score)
from simon s
where s.userId = t1.userId
and s.passageId = t1.passageId
and s.score > t1.s1
) as s2
from
(select userId,passageId,min(score) as S1
from simon
group by userId,passageId) t1;
修改强>
这是我用于同一任务的另一种方法,以便提供可用于更大数据集的有效解决方案。
说实话,我不知道以下方法是否优于前一种方法,因为它包含Group_concat()
和Substring_Index()
之类的功能,这些功能并不是性能友好的。
但是我的后续解决方案的积极意义因为它不需要对数据进行排序(或扫描一组中的整个列),这在我之前的解决方案中发生了两次。
然而,这是我的解决方案:
insert into simon2(userId,passageId,score1,score2)
select t.userId, t.passageId,
substring_index(t.scores,',',1) as score1,
(case when length(t.scores) > 1 then substring_index(t.scores,',',-1)
else null
end
) as score2
from
(select userId,passageId,
substring_index (group_concat(score separator ','),',',2) as scores
from simon
group by userId,passageId) t;
注意:解决方案2不基于score
的任何递增或递减顺序。它将遵循与您在以下查询的结果集中获得的序列相同的序列:
select *from simon;
我认为这是你在问题中实际要求的内容
希望它有所帮助!
答案 1 :(得分:0)
我在postgresql中创建了这个查询(split_part) 明天我将转换为mysql ..希望它会帮助你
select userid,passageid,
split_part(score,',',1)as first,
split_part(score,',',2)as second
from
(
select userid,passageid,
string_agg(score,',')as score
from simon t2
group by userid,passageid
order by userid
)t