使用SQL

时间:2017-10-27 16:42:14

标签: mysql sql pivot-table

如何从以下位置转换表:

 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数据库中工作。

http://rextester.com/UYDRBF97169

2 个答案:

答案 0 :(得分:0)

首先,您应定义订单以获取值。对于每个userIdpassageId,即2个最小分数或2个最高分数。

以下查询将为每对(userId,passageId)获取2个最小分数,并将其分别作为simon2score1存储在表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;

Click for the Demo

修改

这是我用于同一任务的另一种方法,以便提供可用于更大数据集的有效解决方案。

说实话,我不知道以下方法是否优于前一种方法,因为它包含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;

Click here for Demo 2

注意:解决方案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