如果null返回0

时间:2012-07-13 18:21:55

标签: sql sql-server isnull

我正在尝试修改此查询,以便在未返回任何数据时返回在一行或所有行中打印“0”的行。我已经尝试过使用ISNULL(),但我没有到达任何地方。

SELECT DISTINCT 
SA.DELETED,
PAT.VERSION, 
PAT.PATTERNDATE,
SA.AGENT_VERSION,
SCL.COMPUTER_NAME AS Computer_Name,
SCO.OPERATION_SYSTEM AS Operation_System,
dateadd(s,convert(bigint,SA.CREATION_TIME)/1000,
'01-01-1970 00:00:00') CREATION_DTTM,
dateadd(s,convert(bigint,SA.LAST_UPDATE_TIME)/1000,
'01-01-1970  00:00:00')  Lastupdatetime,
DATEADD(s, convert(bigint,LAST_SCAN_TIME)/1000,
'01-01-1970 00:00:00')LAST_SCAN_TIME,
PAT.PATTERNDATE AS Pattern_Date,
SCL.USER_NAME AS User_Name,
VSC.IP_ADDR1_TEXT AS IP_Add,
IM.NAME AS Group_Name

FROM ((((SEM_AGENT SA

INNER JOIN SEM_CLIENT SCL
ON ((SA.COMPUTER_ID=SCL.COMPUTER_ID) 
AND (SA.DOMAIN_ID=SCL.DOMAIN_ID)) 
AND (SA.GROUP_ID=SCL.GROUP_ID)) 

INNER JOIN SEM_COMPUTER   SCO
ON ((SA.COMPUTER_ID=SCO.COMPUTER_ID) 
AND (SA.DOMAIN_ID=SCO.DOMAIN_ID)) 
AND (SA.DELETED=SCO.DELETED))

INNER JOIN PATTERN PAT 
ON SA.PATTERN_IDX=PAT.PATTERN_IDX) 
INNER JOIN IDENTITY_MAP IM 
ON SCL.GROUP_ID=IM.ID) 

INNER JOIN V_SEM_COMPUTER VSC 
ON SCO.COMPUTER_ID=VSC.COMPUTER_ID 
AND SA.DELETED=0

WHERE PAT.Patterndate < (SELECT MAX(Patterndate) -2 FROM Pattern)
AND SCO.OPERATION_SYSTEM NOT LIKE '%2000%'
ORDER BY Computer_Name

4 个答案:

答案 0 :(得分:3)

在没有记录

时返回NULL行的一种方法
  • 将您的SQL放入CTE
  • 使用
  • 从您的CTE中选择
  • 与您的CTE不存在的默认值的联合。


WITH CTE AS (
   SELECT "Computer Name".  ... 
)
SELECT * FROM CTE
UNION ALL
SELECT '', 0, 0, '' 
WHERE 
    NOT EXISTS(SELECT * FROM CTE)
ORDER BY 
     "Computer Name"

请参阅DEMO returns "null" recordDEMO returns data
这两个演示之间的差异是CTE中的Where 1=2Where 1=1

答案 1 :(得分:0)

我会检查您的条件是否有任何行,如果没有,请选择0,否则,选择您的整个查询:

SELECT TOP 1 *
FROM (((("SEM_AGENT" "SEM_AGENT" INNER JOIN "SEM_CLIENT" "SEM_CLIENT"  
  ON (("SEM_AGENT"."COMPUTER_ID"="SEM_CLIENT"."COMPUTER_ID")  
  AND ("SEM_AGENT"."DOMAIN_ID"="SEM_CLIENT"."DOMAIN_ID"))  
  AND ("SEM_AGENT"."GROUP_ID"="SEM_CLIENT"."GROUP_ID")) INNER JOIN "SEM_COMPUTER"   "SEM_COMPUTER"  
  ON (("SEM_AGENT"."COMPUTER_ID"="SEM_COMPUTER"."COMPUTER_ID")  
  AND ("SEM_AGENT"."DOMAIN_ID"="SEM_COMPUTER"."DOMAIN_ID"))  
  AND ("SEM_AGENT"."DELETED"="SEM_COMPUTER"."DELETED")) INNER JOIN "PATTERN" "PATTERN"  
  ON "SEM_AGENT"."PATTERN_IDX"="PATTERN"."PATTERN_IDX") INNER JOIN "IDENTITY_MAP" "IDENTITY_MAP"  
  ON "SEM_CLIENT"."GROUP_ID"="IDENTITY_MAP"."ID") INNER JOIN "V_SEM_COMPUTER" "V_SEM_COMPUTER"  
  ON "SEM_COMPUTER"."COMPUTER_ID"="V_SEM_COMPUTER"."COMPUTER_ID"  
  AND "SEM_AGENT"."DELETED"=0 
WHERE Pattern.Patterndate < (select max(Patterndate) -2 from Pattern) 
AND SEM_COMPUTER.OPERATION_SYSTEM NOT LIKE '%2000%' 

IF @@ROWCOUNT = 0
    SELECT 0
ELSE 
BEGIN
    SELECT DISTINCT "SEM_AGENT"."DELETED" 
      ,"PATTERN"."VERSION"  
      ,"PATTERN"."PATTERNDATE" 
      ,"SEM_AGENT"."AGENT_VERSION" 
      ,"SEM_CLIENT"."COMPUTER_NAME" "Computer Name" 
      , "SEM_COMPUTER"."OPERATION_SYSTEM" "Operation System" 
      ,dateadd(s,convert(bigint,"SEM_AGENT"."CREATION_TIME")/1000,'01-01-1970 00:00:00')     
        CREATION_DTTM 
      , dateadd(s,convert(bigint,"SEM_AGENT"."LAST_UPDATE_TIME")/1000,'01-01-1970  00:00:00')  Lastupdatetime 
      , DATEADD(s, convert(bigint,LAST_SCAN_TIME)/1000, '01-01-1970 00:00:00')"Last Scan Time" 
      , "PATTERN"."PATTERNDATE" "Pattern Date" 
      , "SEM_CLIENT"."USER_NAME" "User Name" 
      , "V_SEM_COMPUTER"."IP_ADDR1_TEXT" "IP Address" 
      , "IDENTITY_MAP"."NAME" "Group Name" 
    FROM (((("SEM_AGENT" "SEM_AGENT" INNER JOIN "SEM_CLIENT" "SEM_CLIENT"  
      ON (("SEM_AGENT"."COMPUTER_ID"="SEM_CLIENT"."COMPUTER_ID")  
      AND ("SEM_AGENT"."DOMAIN_ID"="SEM_CLIENT"."DOMAIN_ID"))  
      AND ("SEM_AGENT"."GROUP_ID"="SEM_CLIENT"."GROUP_ID")) INNER JOIN "SEM_COMPUTER"   "SEM_COMPUTER"  
      ON (("SEM_AGENT"."COMPUTER_ID"="SEM_COMPUTER"."COMPUTER_ID")  
      AND ("SEM_AGENT"."DOMAIN_ID"="SEM_COMPUTER"."DOMAIN_ID"))  
      AND ("SEM_AGENT"."DELETED"="SEM_COMPUTER"."DELETED")) INNER JOIN "PATTERN" "PATTERN"  
      ON "SEM_AGENT"."PATTERN_IDX"="PATTERN"."PATTERN_IDX") INNER JOIN "IDENTITY_MAP" "IDENTITY_MAP"  
      ON "SEM_CLIENT"."GROUP_ID"="IDENTITY_MAP"."ID") INNER JOIN "V_SEM_COMPUTER" "V_SEM_COMPUTER"  
      ON "SEM_COMPUTER"."COMPUTER_ID"="V_SEM_COMPUTER"."COMPUTER_ID"  
      AND "SEM_AGENT"."DELETED"=0 
    WHERE Pattern.Patterndate < (select max(Patterndate) -2 from Pattern) 
    AND SEM_COMPUTER.OPERATION_SYSTEM NOT LIKE '%2000%' 
    ORDER BY "Computer Name" 
END

如果你知道你的内连接不会改变结果的数量,那么你可以从第一个查询中删除它们以提高效率。

如果你不想使用@@ ROWCOUNT,你也可以使用COUNT():

DECLARE @count INT

SELECT @count = COUNT(*)
FROM (
SELECT TOP 1 *
FROM (((("SEM_AGENT" "SEM_AGENT" INNER JOIN "SEM_CLIENT" "SEM_CLIENT"  
  ON (("SEM_AGENT"."COMPUTER_ID"="SEM_CLIENT"."COMPUTER_ID")  
  AND ("SEM_AGENT"."DOMAIN_ID"="SEM_CLIENT"."DOMAIN_ID"))  
  AND ("SEM_AGENT"."GROUP_ID"="SEM_CLIENT"."GROUP_ID")) INNER JOIN "SEM_COMPUTER"   "SEM_COMPUTER"  
  ON (("SEM_AGENT"."COMPUTER_ID"="SEM_COMPUTER"."COMPUTER_ID")  
  AND ("SEM_AGENT"."DOMAIN_ID"="SEM_COMPUTER"."DOMAIN_ID"))  
  AND ("SEM_AGENT"."DELETED"="SEM_COMPUTER"."DELETED")) INNER JOIN "PATTERN" "PATTERN"  
  ON "SEM_AGENT"."PATTERN_IDX"="PATTERN"."PATTERN_IDX") INNER JOIN "IDENTITY_MAP" "IDENTITY_MAP"  
  ON "SEM_CLIENT"."GROUP_ID"="IDENTITY_MAP"."ID") INNER JOIN "V_SEM_COMPUTER" "V_SEM_COMPUTER"  
  ON "SEM_COMPUTER"."COMPUTER_ID"="V_SEM_COMPUTER"."COMPUTER_ID"  
  AND "SEM_AGENT"."DELETED"=0 
WHERE Pattern.Patterndate < (select max(Patterndate) -2 from Pattern) 
AND SEM_COMPUTER.OPERATION_SYSTEM NOT LIKE '%2000%' ) temp

IF @count = 0
SELECT 0
ELSE 
BEGIN
    SELECT DISTINCT "SEM_AGENT"."DELETED" 
      ,"PATTERN"."VERSION"  
      ,"PATTERN"."PATTERNDATE" 
      ,"SEM_AGENT"."AGENT_VERSION" 
      ,"SEM_CLIENT"."COMPUTER_NAME" "Computer Name" 
      , "SEM_COMPUTER"."OPERATION_SYSTEM" "Operation System" 
      ,dateadd(s,convert(bigint,"SEM_AGENT"."CREATION_TIME")/1000,'01-01-1970 00:00:00')     
        CREATION_DTTM 
      , dateadd(s,convert(bigint,"SEM_AGENT"."LAST_UPDATE_TIME")/1000,'01-01-1970  00:00:00')  Lastupdatetime 
      , DATEADD(s, convert(bigint,LAST_SCAN_TIME)/1000, '01-01-1970 00:00:00')"Last Scan Time" 
      , "PATTERN"."PATTERNDATE" "Pattern Date" 
      , "SEM_CLIENT"."USER_NAME" "User Name" 
      , "V_SEM_COMPUTER"."IP_ADDR1_TEXT" "IP Address" 
      , "IDENTITY_MAP"."NAME" "Group Name" 
    FROM (((("SEM_AGENT" "SEM_AGENT" INNER JOIN "SEM_CLIENT" "SEM_CLIENT"  
      ON (("SEM_AGENT"."COMPUTER_ID"="SEM_CLIENT"."COMPUTER_ID")  
      AND ("SEM_AGENT"."DOMAIN_ID"="SEM_CLIENT"."DOMAIN_ID"))  
      AND ("SEM_AGENT"."GROUP_ID"="SEM_CLIENT"."GROUP_ID")) INNER JOIN "SEM_COMPUTER"   "SEM_COMPUTER"  
      ON (("SEM_AGENT"."COMPUTER_ID"="SEM_COMPUTER"."COMPUTER_ID")  
      AND ("SEM_AGENT"."DOMAIN_ID"="SEM_COMPUTER"."DOMAIN_ID"))  
      AND ("SEM_AGENT"."DELETED"="SEM_COMPUTER"."DELETED")) INNER JOIN "PATTERN" "PATTERN"  
      ON "SEM_AGENT"."PATTERN_IDX"="PATTERN"."PATTERN_IDX") INNER JOIN "IDENTITY_MAP" "IDENTITY_MAP"  
      ON "SEM_CLIENT"."GROUP_ID"="IDENTITY_MAP"."ID") INNER JOIN "V_SEM_COMPUTER" "V_SEM_COMPUTER"  
      ON "SEM_COMPUTER"."COMPUTER_ID"="V_SEM_COMPUTER"."COMPUTER_ID"  
      AND "SEM_AGENT"."DELETED"=0 
    WHERE Pattern.Patterndate < (select max(Patterndate) -2 from Pattern) 
    AND SEM_COMPUTER.OPERATION_SYSTEM NOT LIKE '%2000%' 
    ORDER BY "Computer Name" 
END

答案 2 :(得分:0)

您有一个返回0行或更多行的查询。当它返回0行时,您希望包含另一行。

这增加了查询的计算复杂性。一种方法是将所需的行连接在一起,以及指示行来自何处​​的标志。然后,使用windows函数在所有行之间共享该信息,并使用where子句过滤最后的行:

select *
from (select t.*, sum(FromQ) over (partition by NULL) as numQ
      from (select *, 1 as FromQ
            from <query>
            union all
            select 0,0,0,0 . . . , 0 as FromQ
           ) t
      ) t
where numQ = 0 or numQ > 0 and FromQ <> 0

您也可以将组合并在一起,反过来按FromQ排序,如果不是第一个,则忽略应用程序中的行。

答案 3 :(得分:0)

我把它分成三个陈述:

DECLARE @RecordCount int;

WITH Temp_CTE
AS
(
SELECT DISTINCT EM_AGENT.DELETED
  ,PATTERN.VERSION 
  ,PATTERN.PATTERNDATE
  ,SEM_AGENT.AGENT_VERSION
  ,SEM_CLIENT.COMPUTER_NAME "Computer Name"
  ,SEM_COMPUTER.OPERATION_SYSTEM "Operation System"
  ,dateadd(s,convert(bigint,SEM_AGENT.CREATION_TIME)/1000
    ,'01-01-1970 00:00:00') CREATION_DTTM
  , dateadd(s,convert(bigint,SEM_AGENT.LAST_UPDATE_TIME)/1000
    ,'01-01-1970  00:00:00') Lastupdatetime
  , DATEADD(s, convert(bigint,LAST_SCAN_TIME)/1000
    , '01-01-1970 00:00:00') "Last Scan Time"
  , PATTERN.PATTERNDATE "Pattern Date"
  , SEM_CLIENT.USER_NAME "User Name"
  , V_SEM_COMPUTER.IP_ADDR1_TEXT "IP Address"
  , IDENTITY_MAP.NAME "Group Name"
FROM (((("SEM_AGENT" "SEM_AGENT" 
INNER JOIN "SEM_CLIENT" "SEM_CLIENT" 
  ON (("SEM_AGENT"."COMPUTER_ID"="SEM_CLIENT"."COMPUTER_ID") 
  AND ("SEM_AGENT"."DOMAIN_ID"="SEM_CLIENT"."DOMAIN_ID")) 
  AND ("SEM_AGENT"."GROUP_ID"="SEM_CLIENT"."GROUP_ID")) 
INNER JOIN "SEM_COMPUTER"   "SEM_COMPUTER" 
  ON (("SEM_AGENT"."COMPUTER_ID"="SEM_COMPUTER"."COMPUTER_ID") 
  AND ("SEM_AGENT"."DOMAIN_ID"="SEM_COMPUTER"."DOMAIN_ID")) 
  AND ("SEM_AGENT"."DELETED"="SEM_COMPUTER"."DELETED"))
INNER JOIN "PATTERN" "PATTERN" 
  ON "SEM_AGENT"."PATTERN_IDX"="PATTERN"."PATTERN_IDX") 
INNER JOIN "IDENTITY_MAP" "IDENTITY_MAP" 
  ON "SEM_CLIENT"."GROUP_ID"="IDENTITY_MAP"."ID") 
INNER JOIN "V_SEM_COMPUTER" "V_SEM_COMPUTER" 
  ON "SEM_COMPUTER"."COMPUTER_ID"="V_SEM_COMPUTER"."COMPUTER_ID" 
  AND "SEM_AGENT"."DELETED"=0
WHERE Pattern.Patterndate < (select max(Patterndate) -2 from Pattern)
  AND SEM_COMPUTER.OPERATION_SYSTEM NOT LIKE '%2000%'
)
SELECT @RecordCount = COUNT(*) FROM Temp_CTE;

IF @RecordCount=0 THEN
  SELECT 0
ELSE
  SELECT * FROM Temp_CTE ORDER BY [Computer Name];