【问题标题】:Display 2 columns for each header每个标题显示 2 列
【发布时间】:2013-08-14 11:07:04
【问题描述】:

在 SQL Server 2008 中,我有一个表 People(Id、Gender、Name)。 性别为男性或女性。可以有很多人同名。 我想写一个查询,显示每个性别的前 2 个名字 按计数及其计数,如下所示:

  Male        Female
Adam   23    Rose  34
Max    20    Jenny 15

我认为可能会使用 PIVOT,但我看到的所有示例都只显示每个标题的一列。

【问题讨论】:

    标签: sql sql-server tsql pivot


    【解决方案1】:

    这是一个关于 SQL Fiddle 的例子——http://sqlfiddle.com/#!3/b3477/1

    这使用了几个常用的表格表达式来分隔性别。

    create table People 
    (
     Id int, 
     Gender varchar(50), 
     Name varchar(50)
    )
    ;
    
    insert into People values (1, 'Male', 'Bob');
    insert into People values  (2, 'Male', 'Bob');
    insert into People values  (3, 'Male', 'Bill');
    insert into People values (4, 'Male', 'Chuck');
    
    insert into People values (5, 'Female', 'Anne');
    insert into People values (6, 'Female', 'Anne');
    insert into People values (7, 'Female', 'Bobbi');
    insert into People values (8, 'Female', 'Jane');
    
    with cteMale as
    (
    
        select Name as 'MaleName', Count(*) as Num, ROW_NUMBER() over(order by count(*) desc, Name) RowNum
        from People 
        where Gender = 'Male'
        group by Name
    
    )
    ,
     cteFemale as
    (
      select top 2 Name as 'FemaleName', Count(*) as Num, ROW_NUMBER() over(order by count(*) desc, Name) RowNum
      from People 
      where Gender = 'Female'
      group by Name
    
    )
    
    select a.MaleName, a.Num as MaleNum, b.femaleName, b.Num as FemaleNum
    from cteMale a
      join cteFemale b on 
        a.RowNum = b.RowNum
    where a.RowNum <= 2
    

    【讨论】:

      【解决方案2】:

      使用窗口函数。以下是使用临时表 #people 的完整解决方案。

      -- 使用临时数据库
      使用临时数据库;

      -- 跌落测试表
      --drop table #people;
      --go

      -- 创建测试表
      创建表 #people (my_id int, my_gender char(1), my_name varchar(25));

      --清除测试表
      从#people 中删除;

      -- 三个计数
      插入 #people 价值观
      (23, 'M', '亚当'),
      (34, 'F', '玫瑰');
      去 3

      -- 两个计数
      插入 #people 价值观
      (20, 'M', '最大'),
      (15, 'F', '珍妮');
      去 2

      -- 一个计数
      插入 #people 价值观
      (20, 'M', '约翰'),
      (15, 'F', '朱莉');

      -- 按性别抢前两名
      ;
      使用 cte_Get_Top_Two 作为
      (
      选择 ROW_NUMBER() OVER(PARTITION BY my_gender ORDER BY count() DESC) AS my_window,
      my_gender, my_name, count(
      ) 总计
      来自#people
      按 my_gender、my_name 分组
      )
      select * from cte_Get_Top_Two where my_window in (1, 2)


      这是输出。

      PS:您可以从表中删除 my_id,因为它与您的问题无关,但不会更改解决方案。

      【讨论】:

      • 我希望 F 和 M 成为标题,而不是行。查尔斯的回答对我有用。
      • 数据库使用关系代数。 IE - 行,如果您希望它打印得漂亮,请使用报告工具。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-05
      • 2013-10-13
      • 1970-01-01
      • 2017-11-11
      • 1970-01-01
      相关资源
      最近更新 更多