如果前一列单元格为NULL,是否可以将SQL Server数据沿一列向左移动?

时间:2018-04-11 15:36:54

标签: sql-server sql-update

我有一些像这样的查询结果(但是在10行的000行中);

Pol_Ref    ¦  Pol_Mix  ¦  Pol_1_Type ¦ Pol_2_Type ¦  Pol_3_Type ¦  Pol_4_Type
===========================================================================
XXXXXXSW01 ¦    Car    ¦   NULL      ¦     PC     ¦     NULL    ¦   NULL
XXXXXXSW02 ¦    Modern ¦   NULL      ¦     PC     ¦     MB      ¦   NULL
XXXXXXSW01 ¦    Car    ¦   NULL      ¦     NULL   ¦     PC      ¦   NULL 
XXXXXXSW03 ¦    Modern ¦   PC        ¦     NULL   ¦     MB      ¦   NULL

列[Pol_1_Type]应始终使用保险策略类型作为最小值,然后填充其后的任何其他列,但按从左到右的顺序排列。由于最终用户错误(不要去那里),他们有时会使用系统中的错误字段对它们进行设置,因此您最终会在这些列的所有位置得到值。

如果在值之前出现NULL,是否有一种方法可以将所有值沿着左边的值移动?所以看起来应该是这样的;

Pol_Ref    ¦  Pol_Mix  ¦  Pol_1_Type ¦ Pol_2_Type ¦  Pol_3_Type ¦  Pol_4_Type
===========================================================================
XXXXXXSW01 ¦    Car    ¦   PC        ¦     NULL   ¦     NULL    ¦   NULL
XXXXXXSW02 ¦    Modern ¦   PC        ¦     PC     ¦     MB      ¦   NULL
XXXXXXSW01 ¦    Car    ¦   PC        ¦     NULL   ¦     NULL    ¦   NULL 
XXXXXXSW03 ¦    Modern ¦   PC        ¦     MB     ¦     NULL    ¦   NULL

2 个答案:

答案 0 :(得分:1)

这并没有给出你所追求的答案,但我相信这是因为SW02PC两次。我相信应该只有一次。这给出了:

CREATE TABLE #Policy (Pol_ref varchar(10),
                      Pol_mix varchar(10),
                      Pol_1_Type char(2),
                      Pol_2_Type char(2),
                      Pol_3_Type char(2),
                      Pol_4_Type char(2));
INSERT INTO #Policy
VALUES ('XXXXXXSW01','Car',NULL,'PC',NULL,NULL),
       ('XXXXXXSW02','Modern',NULL,'PC','MB',NULL),
       ('XXXXXXSW01','Car',NULL,NULL,'PC',NULL),
       ('XXXXXXSW03','Modern','PC',NULL,'MB',NULL);
GO

SELECT *
FROM #Policy;
GO

SELECT Pol_ref,
       Pol_mix,
       COALESCE(Pol_1_Type,Pol_2_Type,Pol_3_Type,Pol_4_Type) AS Pol_1_Type,
       CASE WHEN Pol_1_Type IS NOT NULL THEN COALESCE(Pol_2_Type,Pol_3_Type,Pol_4_Type)
            ELSE COALESCE(Pol_3_Type,Pol_4_Type)
       END AS Pol_2_Type,
       CASE WHEN Pol_1_Type IS NOT NULL AND Pol_2_Type IS NOT NULL THEN COALESCE(Pol_3_Type,Pol_4_Type)
            WHEN Pol_1_Type IS NOT NULL AND Pol_2_Type IS NULL THEN Pol_4_Type
            WHEN Pol_2_Type IS NOT NULL AND Pol_1_Type IS NULL THEN Pol_4_Type
       END AS Pol_3_Type,
       CASE WHEN Pol_1_Type IS NOT NULL AND Pol_2_Type IS NOT NULL AND Pol_3_Type IS NOT NULL THEN Pol_4_Type END AS Pol_4_Type
FROM #Policy

GO
DROP TABLE #Policy;
GO

答案 1 :(得分:0)

正如我在评论中所说,您的预期结果与您的样本数据不符。具体而言,您向PC添加了XXXXXXSW02。您还没有显示该表的PK是什么。考虑到这一点,这应该让你开始:

--load up the sample data you provided
declare @table table (Pol_Ref varchar(64),Pol_Mix varchar(16),Pol_1_Type char(2) null, Pol_2_Type  char(2) null, Pol_3_Type  char(2) null,  Pol_4_Type char(2) null)
insert into @table
values
('XXXXXXSW01','Car ',NULL,'PC',NULL,PC),      --I've added a PC here
('XXXXXXSW02','Modern',NULL,'PC','MB',NULL),
('XXXXXXSW01','Car',NULL,NULL,'PC',NULL), 
('XXXXXXSW03','Modern','PC',NULL,'MB',NULL)

--create a place holder primary key
;with cte as(select 
                ID = row_number() over (order by (select null))
                ,* 
                from @table)


--use aggregates with unpivot
select
    p.ID
    ,p.Pol_Ref
    ,p.Pol_Mix
    ,Pol_1_Type  =  max(case when RN = 1 then Pol end)
    ,Pol_2_Type  =  max(case when RN = 2 then Pol end)
    ,Pol_3_Type  =  max(case when RN = 3 then Pol end)
    ,Pol_4_Type  =  max(case when RN = 4 then Pol end)
from(
        select 
            ID
            ,Pol_Ref
            ,Pol_Mix
            ,Pol
            ,RN = row_number() over (partition by ID order by (select null))
        from
        (select 
            ID
            ,Pol_Ref
            ,Pol_Mix
            ,Pol_1_Type
            ,Pol_2_Type
            ,Pol_3_Type
            ,Pol_4_Type from cte) as t
        unpivot
        (
            Pol for Pols in (Pol_1_Type, Pol_2_Type, Pol_3_Type, Pol_4_Type)
        ) as up
    ) p
group by
    p.Pol_Ref
    ,p.Pol_Mix
    ,p.ID
order by
    Pol_Ref

<强>结果

+----+------------+---------+------------+------------+------------+------------+
| ID |  Pol_Ref   | Pol_Mix | Pol_1_Type | Pol_2_Type | Pol_3_Type | Pol_4_Type |
+----+------------+---------+------------+------------+------------+------------+
|  1 | XXXXXXSW01 | Car     | PC         | PC         | NULL       | NULL       |
|  3 | XXXXXXSW01 | Car     | PC         | NULL       | NULL       | NULL       |
|  2 | XXXXXXSW02 | Modern  | PC         | MB         | NULL       | NULL       |
|  4 | XXXXXXSW03 | Modern  | PC         | MB         | NULL       | NULL       |
+----+------------+---------+------------+------------+------------+------------+

随意为样本数据添加值以进一步测试。