2012-07-13 153 views
-1

我試圖修改此查詢,以返回一個'0'的行打印在任何一個或所有的行中,當沒有數據返回。我試過使用ISNULL(),但我沒有得到任何地方。如果爲空返回0

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 
+6

你能提供具有相同的功能的例子稍小的例子嗎? – Misch 2012-07-13 18:24:24

+6

這是非常難以閱讀。 – deefour 2012-07-13 18:25:03

+0

您使用的是什麼RDBMS? – 2012-07-13 18:26:01

回答

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 
+0

返回「爲'temp'多次指定了'DOMAIN_ID'列'」。 – Ben 2012-07-13 18:53:08

+0

這是因爲我說select *和你的列表具有相同的名稱 - 只是將星號改爲特定列或專門列出所有列與他們的表標識符。 – Erica 2012-07-13 19:15:29

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

一種方法時沒有記錄是

  • 把你的SQL的CTE
  • 選擇您的CTE具有默認值的
  • 一個聯盟有了一個不返回一個NULL行存在對你的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

+0

我試過並收到「ORDER BY子句在視圖,內聯函數,派生表,子查詢和公用表表達式中是無效的,除非還指定了TOP或FOR XML。」 – Ben 2012-07-13 18:52:34

+1

@Ben您只需將訂單從CTE移至UNION後。請參閱更新 – 2012-07-13 19:01:26

+0

謝謝,我試過這個更新並且仍然收到相同的錯誤。 – Ben 2012-07-13 19:05:04

0

我打破了它分成三個語句Where 1=2Where 1=1

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]; 
+0

這一個也返回「列'DOMAIN_ID'爲'temp'指定了多次。「 – Ben 2012-07-13 19:01:47

+0

@Ben嗯。我沒有返回DOMANIN_ID。但是,我確實發現我錯過了'WITH Temp_CTE'字段選擇中的逗號。我修改了我的答案來解決這個問題。 – 2012-07-13 19:07:43