需要一些帮助解决SQL分组问题

时间:2018-11-21 14:45:30

标签: sql sql-server tsql

我会直接追逐。我目前将一张较大的桌子缩小为如下所示:

 Key    Group    Data1    Data2    Data3
=====  =======  =======  =======  =======
 AAA     A         1        0        0
 ASD     A         1        1        0
 FSD     A         1        0        1
 BAS     A         1        1        1
 CDR     B         1        1        1
 KLW     B         1        0        1

以下是创建和填充代码:

CREATE TABLE #DataGroups
(
    [Key]   VARCHAR(25),
    [Group] VARCHAR(25),
    [Data1] BIT,
    [Data2] BIT,
    [Data3] BIT
)

INSERT INTO #DataGroups VALUES
('AAA', 'A', 1, 0, 0),
('ASD', 'A', 1, 1, 0),
('FSD', 'A', 1, 0, 1),
('BAS', 'A', 1, 1, 1),
('CDR', 'B', 1, 1, 1),
('KLW', 'B', 1, 0, 1)

约束如下:

  • “键”是唯一的
  • (“组”,“数据1”,“数据2”,“数据3”)是唯一的
  • “ Data1”将始终为1(但是我不知道这是否与解决方案相关,我们可以假定它可能并不总是1)

我需要做的是制定一个查询,该查询以以下方式重新排列数据:

 Group     Data1     Data12    Data13    Data123
=======  ========  =========  ========  =========
   A        AAA       ASD        FSD       BAS
   B        NULL      NULL       KLW       CDR

根据此表,我需要根据每个组的数据值获取密钥。因此,对于数据1列,我需要在数据1 = 1,数据2 = 0和数据3 = 0的组中获取键。请告诉我是否应该澄清这是否没有道理。

我对SQL不太了解,所以我希望尽可能简洁。我知道,由于将行数据转换为列,因此很可能需要使用PIVOT,但我不确定。甚至对我需要使用哪种类型的函数/聚合提供一点帮助也将不胜感激。

很抱歉,我曾尝试提出自己的解决方案以尝试开始使用PIVOT,但我似乎无法尽我所能来解决问题。

2 个答案:

答案 0 :(得分:2)

您似乎想要这样的东西:

select group,
       max(case when data1 = 1 and data2 = 0 and data3 = 0 then key end) as data1,
       max(case when data1 = 1 and data2 = 1 and data3 = 0 then key end) as data12,
       max(case when data1 = 1 and data2 = 0 and data3 = 1 then key end) as data13,
       max(case when data1 = 1 and data2 = 1 and data3 = 1 then key end) as data123
from #DataGroups dg
group by group

答案 1 :(得分:1)

我会使用Gordon's solution。但是为了好玩,这里是基于数学/数据透视的解决方案,基于我们可以将这些位组合成一个数字的事实:

declare @DataGroups table
(
    [Key]   VARCHAR(25),
    [Group] VARCHAR(25),
    [Data1] BIT,
    [Data2] BIT,
    [Data3] BIT
)

INSERT INTO @DataGroups VALUES
('AAA', 'A', 1, 0, 0),
('ASD', 'A', 1, 1, 0),
('FSD', 'A', 1, 0, 1),
('BAS', 'A', 1, 1, 1),
('CDR', 'B', 1, 1, 1),
('KLW', 'B', 1, 0, 1)

;With Basics as (
select
    [Group],[Key],Data1 + (2 * data2) + (4 * data3) as Total
from
    @DataGroups dg
)
select
    [Group],[1] as Data1,[3] as Data12,[5] as Data13,[7] as Data123
from
    Basics
        pivot
    (MAX([Key]) for Total in ([1],[3],[5],[7])) v

请注意,在透视 1 之前,我们必须使用子查询/ CTE从结果集中删除 Data1等列,因为否则构成数据透视表分组列的隐式集合的一部分,并且我们不折叠任何行。将select中的Basics更改为使用*,Data1 + (2 * data2) + (4 * data3) as Total来查看其外观。

结果:

Group    Data1    Data12   Data13   Data123
-------- -------- -------- -------- ---------
A        AAA      ASD      FSD      BAS
B        NULL     NULL     KLW      CDR

1 我一直对此感到困扰,因此决定是时候添加一个feedback issue了,看看是否可以改进SQL Server。