How to replace the NULL values in a pivot output with zeroes?

南楼画角 提交于 2020-01-06 05:02:47

问题


Following the answer from a previous question I want to get rid of some NULL values when I do not have a number for some cases

I have the following query

CREATE TABLE [MYTABLE]
  (
      [A] int
    , [B] int
    , [VAL] float
  );

INSERT INTO [MYTABLE] ([A], [B], [VAL]) VALUES
    (1, 1, -218.46),
    (1, 2, -2.1846000000000e+02),
    (2, 1, 6.4000000000000e+01),
    (2, 2, -218.46),
    (2, 3, 6.4000000000000e+01),
    (3, 2, -2.1846000000000e+02),
    (3, 3, -218.46),
    (4, 3, 6.4000000000000e+01),
    (4, 4, -218.46),
    (4, 5, 6.4000000000000e+01),
    (5, 4, 6.4000000000000e+01),
    (5, 5, -218.46),
    (5, 6, 6.4000000000000e+01),
    (6, 5, 6.4000000000000e+01),
    (6, 6, -218.46),
    (6, 7, 6.4000000000000e+01),
    (7, 6, 6.4000000000000e+01),
    (7, 7, -218.46),
    (7, 8, 6.4000000000000e+01),
    (8, 7, 6.4000000000000e+01),
    (8, 8, -218.46),
    (8, 9, 6.4000000000000e+01),
    (9, 8, 6.4000000000000e+01),
    (9, 9, -218.46),
    (9, 10, 6.4000000000000e+01),
    (10, 9, 6.4000000000000e+01),
    (10, 10, -218.46);

SELECT [1],[2],[3],[4],[5],[6],[7],[8],[9],[10]
FROM
(   SELECT  x = a
        ,   y = b
        ,   v = (CASE WHEN IsNumeric(val)=0 THEN 0 ELSE val END)
    FROM    MYTABLE
) AS T
PIVOT
(
    min( v)
    FOR y IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10]) 
) AS pvt
order by x

I am getting the following result:

    1       2      3       4       5       6       7       8       9       10
------- ------- ------- ------- ------- ------- ------- ------- ------- ------- 
-218.46 -218.46   NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL  
64      -218.46    64     NULL    NULL    NULL    NULL    NULL    NULL    NULL  
  NULL  -218.46 -218.46   NULL    NULL    NULL    NULL    NULL    NULL    NULL 
  NULL    NULL     64   -218.46    64     NULL    NULL    NULL    NULL    NULL 
  NULL    NULL    NULL     64   -218.46    64     NULL    NULL    NULL    NULL  
  NULL    NULL    NULL    NULL     64   -218.46    64     NULL    NULL    NULL  
  NULL    NULL    NULL    NULL    NULL     64   -218.46    64     NULL    NULL  
  NULL    NULL    NULL    NULL    NULL    NULL     64   -218.46    64     NULL  
  NULL    NULL    NULL    NULL    NULL    NULL    NULL     64   -218.46    64
  NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL     64   -218.46

but I need the following result

    1       2      3       4       5       6       7       8       9       10
------- ------- ------- ------- ------- ------- ------- ------- ------- ------- 
-218.46 -218.46   NULL    NULL     0       0       0       0       0       0    
64      -218.46    64      0       0       0       0       0       0       0    
   0    -218.46 -218.46    0       0       0       0       0       0       0   
   0       0       64   -218.46    64      0       0       0       0       0   
   0       0       0       64   -218.46    64      0       0       0       0    
   0       0       0       0       64   -218.46    64      0       0       0    
   0       0       0       0       0       64   -218.46    64      0       0    
   0       0       0       0       0       0       64   -218.46    64      0    
   0       0       0       0       0       0       0       64   -218.46    64
   0       0       0       0       0       0       0       0       64   -218.46

How do I replace all NULL values with 0's?

EDIT

Following @Siva answer

CREATE TABLE [dbo].[Matrix]
(
        [A]     INT
    ,   [B]     INT
    ,   [VAL]   FLOAT
);

INSERT INTO [dbo].[Matrix] ([A], [B], [VAL]) 
    VALUES
        (1, 1, -218.46)
    ,   (1, 2, -2.1846000000000e+02)
    ,   (2, 1, 6.4000000000000e+01)
    ,   (2, 2, -218.46)
    ,   (2, 3, 6.4000000000000e+01)
    ,   (3, 2, -2.1846000000000e+02)
    ,   (3, 3, -218.46)
    ,   (4, 3, 6.4000000000000e+01)
    ,   (4, 4, -218.46)
    ,   (4, 5, 6.4000000000000e+01)
    ,   (5, 4, 6.4000000000000e+01)
    ,   (5, 5, -218.46)
    ,   (5, 6, 6.4000000000000e+01)
    ,   (6, 5, 6.4000000000000e+01)
    ,   (6, 6, -218.46)
    ,   (6, 7, 6.4000000000000e+01)
    ,   (7, 6, 6.4000000000000e+01)
    ,   (7, 7, -218.46)
    ,   (7, 8, 6.4000000000000e+01)
    ,   (8, 7, 6.4000000000000e+01)
    ,   (8, 8, -218.46)
    ,   (8, 9, 6.4000000000000e+01)
    ,   (9, 8, 6.4000000000000e+01)
    ,   (9, 9, -218.46)
    ,   (9, 10, 6.4000000000000e+01)
    ,   (10, 9, 6.4000000000000e+01)
    ,   (10, 10, -218.46);

    SELECT  COALESCE([1], 0)    [1]
        ,   COALESCE([2], 0)    [2]
        ,   COALESCE([3], 0)    [3]
        ,   COALESCE([4], 0)    [4]
        ,   COALESCE([5], 0)    [5]
        ,   COALESCE([6], 0)    [6]
        ,   COALESCE([7], 0)    [7]
        ,   COALESCE([8], 0)    [8]
        ,   COALESCE([9], 0)    [9]
        ,   COALESCE([10], 0)   [10]
    FROM
        (   
            SELECT  x = a
                ,   y = b
                ,   v = val
            FROM    [dbo].[Matrix]
        ) AS dataToPivot
        PIVOT
        (
            MIN(v)
            FOR y IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10])
        ) AS pivoted
    ORDER BY x;

What woul be the best way to do this in a dynamic for, I was thinking to do FOR THE FIRST PART...:

DECLARE @sql  nvarchar(max);
DECLARE @Flag INT;
DECLARE @Size INT;
SET @Flag = 1   
SET @Size = 10 ;
SET @sql = 'SELECT '+ CHAR(13); 
WHILE (@Flag <= @Size) BEGIN
  SET @sql =  @sql + ' COALESCE([' + cast( @Flag as varchar(10))  + '], 0)    ['+ cast( @Flag as varchar(10))+'],'+ CHAR(13)  ;
  SET @Flag = @Flag + 1;  
END
SET @sql = LEFT(@sql, LEN(@sql) - 2)
SET @sql =  @sql + '
 FROM
        (   
            SELECT  x = a
                ,   y = b
                ,   v = val
            FROM    [dbo].[Matrix]
        ) AS dataToPivot
        PIVOT
        (
            MIN(v)
            FOR y IN (';
SET @Flag = 1   
WHILE (@Flag <= @Size) BEGIN
  SET @sql =  @sql + ' [' + cast( @Flag as varchar(10))  + '],';
  SET @Flag = @Flag + 1;  
END 
SET @sql = LEFT(@sql, LEN(@sql) - 1);
SET @sql =  @sql +             
            ')
        ) AS pivoted
    ORDER BY x;'
   print  @sql
exec(@sql);   

回答1:


You can use COALESCE to achieve the result.

SQL Fiddle

CREATE TABLE [dbo].[Matrix]
(
        [A]     INT
    ,   [B]     INT
    ,   [VAL]   FLOAT
);

INSERT INTO [dbo].[Matrix] ([A], [B], [VAL]) 
    VALUES
        (1, 1, -218.46)
    ,   (1, 2, -2.1846000000000e+02)
    ,   (2, 1, 6.4000000000000e+01)
    ,   (2, 2, -218.46)
    ,   (2, 3, 6.4000000000000e+01)
    ,   (3, 2, -2.1846000000000e+02)
    ,   (3, 3, -218.46)
    ,   (4, 3, 6.4000000000000e+01)
    ,   (4, 4, -218.46)
    ,   (4, 5, 6.4000000000000e+01)
    ,   (5, 4, 6.4000000000000e+01)
    ,   (5, 5, -218.46)
    ,   (5, 6, 6.4000000000000e+01)
    ,   (6, 5, 6.4000000000000e+01)
    ,   (6, 6, -218.46)
    ,   (6, 7, 6.4000000000000e+01)
    ,   (7, 6, 6.4000000000000e+01)
    ,   (7, 7, -218.46)
    ,   (7, 8, 6.4000000000000e+01)
    ,   (8, 7, 6.4000000000000e+01)
    ,   (8, 8, -218.46)
    ,   (8, 9, 6.4000000000000e+01)
    ,   (9, 8, 6.4000000000000e+01)
    ,   (9, 9, -218.46)
    ,   (9, 10, 6.4000000000000e+01)
    ,   (10, 9, 6.4000000000000e+01)
    ,   (10, 10, -218.46);

    SELECT  COALESCE([1], 0)    [1]
        ,   COALESCE([2], 0)    [2]
        ,   COALESCE([3], 0)    [3]
        ,   COALESCE([4], 0)    [4]
        ,   COALESCE([5], 0)    [5]
        ,   COALESCE([6], 0)    [6]
        ,   COALESCE([7], 0)    [7]
        ,   COALESCE([8], 0)    [8]
        ,   COALESCE([9], 0)    [9]
        ,   COALESCE([10], 0)   [10]
    FROM
        (   
            SELECT  x = a
                ,   y = b
                ,   v = val
            FROM    [dbo].[Matrix]
        ) AS dataToPivot
        PIVOT
        (
            MIN(v)
            FOR y IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10])
        ) AS pivoted
    ORDER BY x;



回答2:


How about IsNull?

SELECT 
isnull([1], 0) as [1],
isnull([2], 0) as [2],
isnull([3], 0) as [3],
isnull([4], 0) as [4],
isnull([5], 0) as [5],
isnull([6], 0) as [6],
isnull([7], 0) as [7],
isnull([8], 0) as [8],
isnull([9], 0) as [9],
isnull([10], 0) as [10] 
FROM 
(SELECT x=a, y=b, v= CASE WHEN IsNumeric(val)=0 THEN 0 ELSE IsNull(val, 0) END FROM MYTABLE)
as T
PIVOT
( 
min(v)
FOR y IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])  
) AS pvt 
ORDER BY x



回答3:


I used the dynamic pivot technique in this SO question Simple way to transpose columns and rows in Sql?

To put NULLs in my pivot report like below. Does get more messy though.

CREATE TABLE [MYTABLE]
(
    [A] int
    , [B] int
    , [VAL] float
);

INSERT INTO [MYTABLE] ([A], [B], [VAL]) VALUES
(1, 1, -218.46),
(1, 2, -2.1846000000000e+02),
(2, 1, 6.4000000000000e+01),
(2, 2, -218.46),
(2, 3, 6.4000000000000e+01),
(3, 2, -2.1846000000000e+02),
(3, 3, -218.46),
(4, 3, 6.4000000000000e+01),
(4, 4, -218.46),
(4, 5, 6.4000000000000e+01),
(5, 4, 6.4000000000000e+01),
(5, 5, -218.46),
(5, 6, 6.4000000000000e+01),
(6, 5, 6.4000000000000e+01),
(6, 6, -218.46),
(6, 7, 6.4000000000000e+01),
(7, 6, 6.4000000000000e+01),
(7, 7, -218.46),
(7, 8, 6.4000000000000e+01),
(8, 7, 6.4000000000000e+01),
(8, 8, -218.46),
(8, 9, 6.4000000000000e+01),
(9, 8, 6.4000000000000e+01),
(9, 9, -218.46),
(9, 10, 6.4000000000000e+01),
(10, 9, 6.4000000000000e+01),
(10, 10, -218.46);

DECLARE @Sql nvarchar(max), @PvtCols nvarchar(max), @PvtSelect nvarchar(max)

SELECT @PvtSelect = Stuff(
                (
                    SELECT ',IsNull(' + Quotename(B) + ',0) as ' + Quotename(B)
                    FROM MYTABLE mt
                    GROUP BY B
                    ORDER BY B
                    FOR XML PATH(''), TYPE
                    ).value('.', 'NVARCHAR(MAX)') 
                ,1,1,'')

SELECT @PvtCols = Stuff(
                    (
                    SELECT DISTINCT  ',' + Quotename(B) 
                    FROM MYTABLE mt
                    FOR XML PATH(''), TYPE
                    ).value('.', 'NVARCHAR(MAX)') 
                ,1,1,'')

SET @Sql =
'SELECT ' + @PvtSelect + ' 
FROM
(   SELECT  x = a
        ,   y = b
        ,   v = (CASE WHEN IsNumeric(val)=0 THEN 0 ELSE val END)
    FROM    MYTABLE
) AS T
PIVOT
(
    min( v)
    FOR y IN (' + @PvtCols + ') 
) AS pvt
order by x'

EXEC(@SQL)


来源:https://stackoverflow.com/questions/10325538/how-to-replace-the-null-values-in-a-pivot-output-with-zeroes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!