如何基于对列的单个比较将sql表数据从多行转换为仅一行

时间:2018-10-16 18:41:22

标签: sql sql-server-2008 aggregate

我有一个表,该表具有给定公司的 12行,代表特定月份该公司的付款,该表的结构具有 数字代表月份,因此January = [1]February = [2]等。

CREATE TABLE [dbo].[TblMonths](
    [Uid] int not null IDENTITY Primary KEY,
    [Id] [float] NULL,
    [Company] [nvarchar](255) NULL,
    [Days] [float] NULL,
    [Pay] [float] NULL,
    [1] [float] NULL,
    [2] [float] NULL,
    [3] [float] NULL,
    [4] [float] NULL,
    [5] [float] NULL,
    [6] [float] NULL,
    [7] [float] NULL,
    [8] [float] NULL,
    [9] [float] NULL,
    [10] [float] NULL,
    [11] [float] NULL,
    [12] [float] NULL
) ;

insert into [TblMonths] values
(2, 'COMPANY_A',    17,     3   ,0, 0   ,51,0   ,0, 0   ,0  ,0, 0   ,0, 0,  0),
(2, 'COMPANY_A',    18.6,   3   ,0, 0   ,0, 0   ,0, 0   ,56 ,0, 0   ,0, 0,  0),
(2, 'COMPANY_A',    19.2,   5   ,0, 0   ,0, 0   ,0, 0   ,0  ,0, 96  ,0, 0,  0),
(2, 'COMPANY_A',    19.75,  4   ,0, 0   ,0, 0   ,79,0   ,0  ,0, 0   ,0, 0,  0),
(2, 'COMPANY_A',    20,     2   ,0, 0   ,0, 40  ,0, 0   ,0  ,0, 0   ,0, 0,  0),
(2, 'COMPANY_A',    22.5,   2   ,0, 0   ,0, 0   ,0, 0   ,0  ,0, 0   ,0,45,  0),
(2, 'COMPANY_A',    23.5,   2   ,47,0   ,0, 0   ,0, 0   ,0  ,0, 0   ,0, 0,  0),
(2, 'COMPANY_A',    25,     2   ,0, 0   ,0, 0   ,0, 0   ,0  ,0, 0   ,0, 0,  50),
(2, 'COMPANY_A',    26,     2   ,0, 52  ,0, 0   ,0, 0   ,0  ,0, 0   ,0, 0,  0),
(2, 'COMPANY_A',    26.6,   3   ,0, 0   ,0, 0   ,0, 0   ,0  ,80,0   ,0, 0,  0),
(2, 'COMPANY_A',    28.5,   2   ,0, 0   ,0, 0   ,0, 0   ,0  ,0, 0   ,57,0,  0),
(2, 'COMPANY_A',    29.3,   3   ,0, 0   ,0, 0   ,0, 88  ,0  ,0, 0   ,0, 0,  0),
(3, 'COMPANY_B',    13.8,   5   ,0, 0   ,69,0   ,0, 0   ,0  ,0, 0   ,0, 0,  0),
(3, 'COMPANY_B',    15,     2   ,0, 0   ,0, 0   ,0, 0   ,30 ,0, 0   ,0, 0,  0),
(3, 'COMPANY_B',    16,     1   ,0, 0   ,0, 0   ,0, 0   ,0  ,0, 0   ,0,16,  0),
(3, 'COMPANY_B',    20,     3   ,0, 0   ,0, 0   ,0, 0   ,0  ,60,0   ,0, 0,  0),
(3, 'COMPANY_B',    20,     4   ,0, 0   ,0, 0   ,0, 0   ,0  ,0, 0   ,0, 0,  80),
(3, 'COMPANY_B',    20.5,   2   ,0, 0   ,0, 41  ,0, 0   ,0  ,0, 0   ,0, 0,  0),
(3, 'COMPANY_B',    23.25,  4   ,0, 0   ,0, 0   ,0, 0   ,0  ,0,93   ,0, 0,  0),
(3, 'COMPANY_B',    23.3,   3   ,0, 0   ,0, 0   ,70,0   ,0  ,0, 0   ,0, 0,  0),
(3, 'COMPANY_B',    23.5,   2   ,47,0   ,0, 0   ,0, 0   ,0  ,0, 0   ,0, 0,  0),
(3, 'COMPANY_B',    28,     1   ,0, 28  ,0, 0   ,0, 0   ,0  ,0, 0   ,0, 0,  0),
(3, 'COMPANY_B',    29,     3   ,0, 0   ,0, 0   ,0, 87  ,0  ,0, 0   ,0, 0,  0),
(3, 'COMPANY_B',    29.3,   3   ,0, 0   ,0, 0   ,0, 0   ,0  ,0, 0   ,88,0,  0);

我想将每个 Company_X 的所有 12 行都转换为仅 1 行,并在月列的值与"Days" ...

不同
0

例如ID COMPANY JAN FEB MAR APR MAR JUN JUL AGO SEP OCT NOV DEC 2 COMPANY_A 23.5 26 17 20 19.75 29.3 18.6 26.6 19.2 28.5 22.5 25 3 COMPANY_B 23.5 28 13.8 20.5 23.3 29 15 20 23.25 29.3 16 20 on row 7,中具有值 47 ,因此我想在列january上获得 23.5 < / strong>,在"Days"的所有其他行中都有id=2,这就是为什么我要搜索与0不同的值的原因。

对于0february,其值为 52 ,列9的值为 26

对于Days,第一行的值为 51 ,因此我想在列march上的值为 17 ,这样我会得到类似的东西:

"Days"

脚本的外观如何?

1 个答案:

答案 0 :(得分:1)

如果我们可以假设一家公司和ID的月份中没有一个月的非零值以上...如果我们不能假设您希望它们Sum()在一起吗?最小值或最大值?只需相应地调整以下内容。注意:如果为min,则可能必须将else上的0忽略掉,并在min之后合并0。

现在,如果在col 1-12的值都不为0的情况下想要零,则为每个case语句添加else。

RexTester DEMO

SELECT ID
     , Company
     , max(case when [1] <> 0 then Days else 0 end) as JAN
     , max(case when [2] <> 0 then Days else 0 end) as FEB
     , max(case when [3] <> 0 then Days else 0 end) as MAR
     , max(case when [4] <> 0 then Days else 0 end) as APR
     , max(case when [5] <> 0 then Days else 0 end) as MAY
     , max(case when [6] <> 0 then Days else 0 end) as JUN
     , max(case when [7] <> 0 then Days else 0 end) as JUL
     , max(case when [8] <> 0 then Days else 0 end) as AUG
     , max(case when [9] <> 0 then Days else 0 end) as SEP
     , max(case when [10] <> 0 then Days else 0 end) as OCT
     , max(case when [11] <> 0 then Days else 0 end) as NOV
     , max(case when [12] <> 0 then Days else 0 end) as DEC
FROM tblMonths
GROUP BY ID, Company;

给我们:

+----+----+-----------+------+-----+------+------+-------+------+------+------+-------+------+------+-----+
|    | ID |  Company  | JAN  | FEB | MAR  | APR  |  MAY  | JUN  | JUL  | AUG  |  SEP  | OCT  | NOV  | DEC |
+----+----+-----------+------+-----+------+------+-------+------+------+------+-------+------+------+-----+
|  1 |  2 | COMPANY_A | 23,5 |  26 |   17 |   20 | 19,75 | 29,3 | 18,6 | 26,6 |  19,2 | 28,5 | 22,5 |  25 |
|  2 |  3 | COMPANY_B | 23,5 |  28 | 13,8 | 20,5 |  23,3 |   29 |   15 |   20 | 23,25 | 29,3 |   16 |  20 |
+----+----+-----------+------+-----+------+------+-------+------+------+------+-------+------+------+-----+

当然,我已经习惯了两个月的时间MAR和一个AGO时间,所以我调整了这些时间。