如何在PIVOT中用0输出替换(null)值

时间:2012-09-07 16:54:00

标签: sql sql-server pivot

我尝试在PIVOT函数中使用0(零)输出转换(null)值但没有成功。

下面是表格和我试过的语法"

SELECT
CLASS,
[AZ],
[CA],
[TX]
FROM #TEMP
PIVOT (SUM(DATA)
FOR STATE IN ([AZ], [CA], [TX])) AS PVT
ORDER BY CLASS

CLASS   AZ  CA      TX
RICE    10  4       (null)
COIN    30  3        2
VEGIE   (null) (null) 9

我尝试使用ISNULL,但没有效果。

PIVOT SUM(ISNULL(DATA,0)) AS QTY

有人可以查看一下它的语法错误吗?非常感谢!

7 个答案:

答案 0 :(得分:35)

SELECT CLASS,
isnull([AZ],0),
isnull([CA],0),
isnull([TX],0)
FROM #TEMP
PIVOT (SUM(DATA)
FOR STATE IN ([AZ], [CA], [TX])) AS PVT
ORDER BY CLASS

答案 1 :(得分:15)

如果您在pivot语句中使用动态列,则可以使用以下命令:

DECLARE @cols               NVARCHAR(MAX)
DECLARE @colsWithNoNulls    NVARCHAR(MAX)
DECLARE @query              NVARCHAR(MAX)

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(Name) 
            FROM Hospital
            WHERE Active = 1 AND StateId IS NOT NULL
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

SET @colsWithNoNulls = STUFF(
            (
                SELECT distinct ',ISNULL(' + QUOTENAME(Name) + ', ''No'') ' + QUOTENAME(Name)
                FROM Hospital
                WHERE Active = 1 AND StateId IS NOT NULL
                FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

EXEC ('
        SELECT Clinician, ' + @colsWithNoNulls + '
        FROM
        (
            SELECT DISTINCT p.FullName AS Clinician, h.Name, CASE WHEN phl.personhospitalloginid IS NOT NULL THEN ''Yes'' ELSE ''No'' END AS HasLogin
            FROM Person p
            INNER JOIN personlicense pl ON pl.personid = p.personid
            INNER JOIN LicenseType lt on lt.licensetypeid = pl.licensetypeid
            INNER JOIN licensetypegroup ltg ON ltg.licensetypegroupid = lt.licensetypegroupid
            INNER JOIN Hospital h ON h.StateId = pl.StateId
            LEFT JOIN PersonHospitalLogin phl ON phl.personid = p.personid AND phl.HospitalId = h.hospitalid
            WHERE ltg.Name = ''RN'' AND
                pl.licenseactivestatusid = 2 AND
                h.Active = 1 AND
                h.StateId IS NOT NULL
        ) AS Results
        PIVOT
        (
            MAX(HasLogin)
            FOR Name IN (' + @cols + ')
        ) p
')

答案 2 :(得分:11)

在选择数据之前,您无法放置IsNull(),因此您会将IsNull()放在SELECT的最终值周围:

SELECT CLASS,
  IsNull([AZ], 0) as [AZ],
  IsNull([CA], 0) as [CA],
  IsNull([TX], 0) as [TX]
FROM #TEMP
PIVOT 
(
  SUM(DATA)
  FOR STATE IN ([AZ], [CA], [TX])
) AS PVT
ORDER BY CLASS

答案 3 :(得分:2)

有时最好像解析器一样思考,比如T-SQL解析器。在执行语句时,解析器在Pivot部分中没有任何值,并且您在该部分中不能有任何检查表达式。顺便说一下,你可以简单地使用它:

SELECT  CLASS
,   IsNull([AZ], 0)
,   IsNull([CA], 0)
,   IsNull([TX], 0)
    FROM #TEMP
    PIVOT (
        SUM(DATA)
        FOR STATE IN (
            [AZ]
        ,   [CA]
        ,   [TX]
        )
    )   AS  PVT
    ORDER   BY  CLASS

答案 4 :(得分:1)

您必须考虑枢轴集中的所有值。你可以用笛卡尔积来做到这一点。

select pivoted.*
from (
    select cartesian.key1, cartesian.key2, isnull(relationship.[value],'nullvalue') as [value]
    from (
      select k1.key1, k2.key2
      from ( select distinct key1 from relationship) k1
          ,( select distinct key2 from relationship) k2
    ) cartesian
      left outer join relationship on relationship.key1 = cartesian.key1 and  relationship.key2 = carterisan.key2
) data
  pivot (
    max(data.value) for ([key2_v1], [key2_v2], [key2_v3], ...)
  ) pivoted

答案 5 :(得分:0)

要在pivot下修改结果,您可以将列放在选定的字段中,然后相应地修改它们。也许您可以使用DECODE作为使用pivot功能构建的列。

  • Kranti A

答案 6 :(得分:0)

我遇到了类似的问题。 根本原因是(在我的情况下,请使用您的方案)在#temp表中,没有用于
的记录 一种。 CLASS = RICE和STATE = TX
b。 CLASS = VEGIE和(STATE = AZ或STATE = CA)
因此,当MSSQL确实进行数据记录透视时,MSSQL对于MAX,SUM,...(聚合函数)始终显示NULL

以上解决方案(IsNull([AZ],0))都不适合我。但是我确实从这些解决方案中得到了一些想法。谢谢。

对不起,它确实取决于#TEMP表。我只能提供一些建议。
1.确保#TEMP表具有以下条件的记录,即使Data为空。
一种。 CLASS = RICE和STATE = TX
b。 CLASS = VEGIE和(STATE = AZ或STATE = CA) 您可能需要使用笛卡尔积:select A.*, B.* from A, B 2.在#temp的选择查询中,如果您需要使用WHERE联接任何表,则最好将其放在另一个子选择查询中。 (目标是1)
3.在#TEMP表中使用notull(DATA,0)。
4.在进行数据透视之前,请确保已实现目标1。

我无法回答原始问题,因为#temp表的信息不足。 我在这里粘贴了代码作为示例,希望对您有所帮助。

SELECT * FROM (
			SELECT eeee.id as enterprise_id
			, eeee.name AS enterprise_name
			, eeee.indicator_name
			, CONVERT(varchar(12) , isnull(eid.[date],'2019-12-01') , 23) AS data_date
			, isnull(eid.value,0) AS indicator_value
			FROM (select ei.id as indicator_id, ei.name as indicator_name, e.* FROM tbl_enterprise_indicator ei, tbl_enterprise e) eeee												
			LEFT JOIN  (select * from tbl_enterprise_indicator_data WHERE [date]='2020-01-01') eid
					ON  eeee.id = eid.enterprise_id and eeee.indicator_id = enterprise_indicator_id
		) AS P 
		PIVOT 
		(
			SUM(P.indicator_value) FOR P.indicator_name IN(TX,CA)
		) AS T