如何使用SQL创建重组数据的新表?

时间:2017-09-07 18:26:20

标签: mysql sql

如何使用SQL转换以下数据:

 cat    score
 1     2
 1     3
 2     1
 2     3
 2     5
 3     1
 3     2
 3     3
 3     4

创建以下子集:

 cat score1 score2
 1    2     3
 2    1     3
 3    1     2

因此,只有“cat”列中每个值的前两个分数才会被放入转换后的表格中。

1 个答案:

答案 0 :(得分:2)

一种可能的方法是在cat上使用自联接但是a.score< b。分数,以便从b获得下一个最小值。如果你需要做n级深度,这不能很好地扩展。在这种情况下,使用模拟行号的用户变量对每列进行条件聚合可能会更好。

这假设Score1 - X始终是您想要显示最低到最高分数。如果需要,我们也可以从最高到最低,或者我们可以使用规则来管理哪些被选中。

样本:http://rextester.com/NHDS97935

SELECT A.cat, Min(A.score) score1, min(B.Score) score2
FROM SO46102892 A
INNER JOIN SO46102892 B
   on A.cat = B.Cat
  and A.score < B.Score
GROUP BY a.cat;

,并提供:

+----+-----+--------+--------+
|    | cat | score1 | score2 |
+----+-----+--------+--------+
|  1 |   1 |      2 |      3 |
|  2 |   2 |      1 |      3 |
|  3 |   3 |      1 |      2 |
+----+-----+--------+--------+

或者(因为这会提供更好的n分数缩放方法)

DEMO:http://rextester.com/VLCC24693

只需在外部选择中添加一个case语句,即可处理n个得分更多。

在这种情况下,我们通过使用两个用户变量并根据需要调整其值来模拟row_number () over (partition by cat order by cat, score)

单独运行此部分:

SELECT case when cat=@cat then @RN:=@RN+1 else @RN:=1 end RN
     , case when cat=@cat then @cat else @cat:=cat end cat
     , score
FROM (SELECT * FROM SO46102892 ORDER BY cat, score) A
CROSS JOIN (SELECT @RN:=0, @Cat:=0) z

您可以看到每个RN如何为模拟其他RDBMS中提供的row_number功能的每个类别分配1-x。

SELECT cat
     , max(case when RN = 1 then score end) as Score1
     , max(case when RN = 2 then score end) as Score2
     , max(case when RN = 3 then score end) as Score3
     , max(case when RN = 4 then score end) as Score4
     , max(case when RN = 5 then score end) as Score5
FROM (SELECT case when cat=@cat then @RN:=@RN+1 else @RN:=1 end RN
           , case when cat=@cat then @cat else @cat:=cat end cat
           , score
      FROM (SELECT * FROM SO46102892 ORDER BY cat, score) A
      CROSS JOIN (SELECT @RN:=0, @Cat:=0) z
      ) y
GROUP BY cat
ORDER BY cat;

给我们:

+----+-----+--------+--------+--------+--------+--------+
|    | cat | Score1 | Score2 | Score3 | Score4 | Score5 |
+----+-----+--------+--------+--------+--------+--------+
|  1 |   1 |      2 |      3 | NULL   | NULL   | NULL   |
|  2 |   2 |      1 |      3 | 5      | NULL   | NULL   |
|  3 |   3 |      1 |      2 | 3      | 4      | NULL   |
+----+-----+--------+--------+--------+--------+--------+

我们可以通过从外部选择中删除它来排除得分3,4,5。