组中来自多个列的前1个值

时间:2019-11-08 19:40:53

标签: sql sql-server

情况:

每个id都是一个小组的一部分,其中每个id都有自己喜欢的游戏。

输出结构:

+----+--------+-------+-------+-------+
| id | group  | game1 | game2 | game3 |  
+----+--------+-------+-------+-------+
|  1 | brazil | wow   | clash | dofus |  
|  1 | brazil | fifa  | clash| dofus |  
|  1 | brazil | wow   | wakfu | dofus |  
|  2 | korea  | clash | dofus | clash | 
|  2 | korea  | clash | dofus | clash |  
|  3 | france | wow   | fifa  | nfl   | 
|  3 | france | wow   | fifa  | nfl   |  
+----+--------+-------+-------+-------+

目标:

我需要按组取游戏1,游戏2,游戏3的前1个值。前1名是该栏中出现次数最多的游戏。

结果应如下所示:

+--------+--------+-------+-------+
| group  | game1  | game2 | game3 |
+--------+--------+-------+-------+
| brazil | wow    | clash | dofus |
| korea  | clash  | dofus | clash |
| france | wow    | fifa  | nfl   |
+--------+--------+-------+-------+

数据:

create table #t1 (id int,[group] varchar(10),game1 varchar(10),game2 varchar(10),game3 varchar(10))

insert into #t1 values 
(1, 'brazil','wow','clash','dofus'),
(1, 'brazil','fifa','clash','dofus'),
(1, 'brazil','wow','wakfu','dofus'),
(2, 'korea','clash','dofus','clash'),
(2, 'korea','clash','dofus','clash'),
(3, 'france','wow','fifa','nfl'),
(3, 'france','wow','fifa','nfl')    

3 个答案:

答案 0 :(得分:2)

我将建议cross apply

select t.group, g1.game1, g2.game2, g3.game3
from (select distinct group
      from #t1 t
     ) t cross apply
     (select top (1) game1
      from #t1 t
      group by game1
      order by count(*) desc
     ) g1 cross apply
     (select top (1) game2
      from #t1 t
      group by game2
      order by count(*) desc
     ) g2 cross apply
     (select top (1) game3
      from #t1 t
      group by game3
      order by count(*) desc
     ) g3;

答案 1 :(得分:1)

使用class Comment extends Model { protected $table = 'comments'; public function author() { return $this->belongsTo('App\Models\User', 'user_id'); } public function replies() { return $this->hasMany('App\Models\Comment', 'parent_id'); } } public function up() { Schema::create('comments', function (Blueprint $table) { $table->bigIncrements('id'); $table->integer('user_id')->unsigned(); $table->integer('parent_id')->unsigned(); $table->integer('commentable_id')->unsigned(); $table->string('commentable_type'); $table->text('body'); $table->timestamps(); }); } 将所有3列变成1列,然后在其上进行汇总:

CTE

请参见demo
结果:

UNION

答案 2 :(得分:0)

首先,如果我认为有任何意义,请重命名标题为 group 的列。尽管我假设您可能已经输入了这种信息进行解释,但由于保留了它,可能会给您带来错误(或者,如果使用了括号,则不会)。如果有的话,它将使其更易于阅读。

在其他新闻中,如果您可以使用CTE,建议您:

    ;WITH Set1 AS
    (
        SELECT id, GameGroup, game1, 
        ROW_NUMBER() OVER (PARTITION BY [id] ORDER BY id ASC, count(game1) DESC) rn
        FROM #t1
        GROUP BY id, GameGroup, game1
    ), 
    Set2 AS
    (
        SELECT id, GameGroup, game2, 
        ROW_NUMBER() OVER (PARTITION BY [id] ORDER BY id ASC, count(game2) DESC) rn
        FROM #t1
        GROUP BY id, GameGroup, game2
    ),
    Set3 AS
    (
        SELECT id, GameGroup, game3, 
        ROW_NUMBER() OVER (PARTITION BY [id] ORDER BY id ASC, count(game3) DESC) rn
        FROM #t1
        GROUP BY id, GameGroup, game3
    )

    SELECT a.GameGroup, a.game1, b.game2, c.game3
    FROM Set1 a
    INNER JOIN Set2 b
      ON a.id = b. id AND a.rn = b.rn
    INNER JOIN Set3 c
      ON a.id = c.id AND a.rn = c.rn
    WHERE a.rn = 1

列出的示例here