2012-07-25 77 views
0

我有三個表,如下所述:SQL NOT EXISTS條件

dbo.ServiceEntry 
ID RunLogEntry Reconciled 
1 0   1 
2 4   1 
3 5   1 

dbo.ServiceEntryPart 
ID ServiceEntryID PartId  ServiceEntryTypeID 
1 1    3   1 
2 2    4   2 
3 2    4   1,2 

dbo.Part 
ID Desc  Active (bitfield) 
3 xyz  1 
4 abc  1 

查詢,如下所示:

SELECT * 
    FROM ServiceEntry AS S 

WHERE (S.RunLogEntryID is not null) AND ([email protected]) 
    AND EXISTS (SELECT ServiceEntryID 
       FROM ServiceEntryPart SEP 
       JOIN Part on SEP.PartID = Part.ID  
       WHERE ((@ActivePart = 0 AND Part.Active is not null) 
        OR (@ActivePart = 1 and Part.Active = 0))  
        AND (@ServiceTypes is null 
        OR CHARINDEX(','+cast(SEP.ServiceTypeIDs as varchar(255))+',',','[email protected]+',') > 0)) 
    OR (NOT EXISTS (SELECT ServiceEntryID 
         FROM ServiceEntryPart SEP 
         JOIN Part on SEP.PartID = Part.ID)) 

服務條目包含的0 runlogentry ID一些記錄如果runlogentryid值服務條目表爲0,那麼該服務條目將不存在服務條目部分記錄。這就是爲什麼我把他們分成兩個,因爲你會發現從查詢例如存在和不存在。 exists語句負責所有具有服務條目部分的服務條目,對於這些條目,過濾器將適用。如果過濾器有值,則不需要不存在的塊,因爲過濾器servicetypeids和activepart僅用於具有服務入口部分的記錄。 換句話說,如果沒有params通過,第一個存在塊獲取具有服務部分的服務條目,而不存在獲取runlogentry id爲0或NOT null的服務條目。這很有效。問題是,當參數通過時,我需要排除沒有服務入口部分的服務入口,並且當它們出現時,我不會得到很好的結果。我希望我做了一個好工作解釋這個問題..請幫助

+0

您的更新說明大多是合理的。但是你的數據與你陳述的規則相矛盾。您聲明如果ServiceEntry.RunLogEntry = 0,則不存在ServiceEntryPart記錄。然而ServiceEntry.ID = 1與該陳述相矛盾。此外,語句*「不存在獲取runlogentry id爲0或非空的服務條目」*對我沒有意義。我相信你的意思是說*「0或NULL」*。但是由於ServiceEntryID = 1,這不是真的。 – dbenham 2012-07-25 11:34:59

回答

0

沒有試圖瞭解你的SQL的其餘部分,如果你想要做的就是避免NOT EXISTS子句,當你的參數爲null時,你可以做類似這個。

SELECT * 
    FROM ServiceEntry AS S 
    JOIN  
WHERE (S.RunLogEntryID is not null) AND ([email protected]) 
    AND EXISTS (SELECT ServiceEntryID 
       FROM ServiceEntryPart SEP 
       JOIN Part on SEP.PartID = Part.ID  
       WHERE ((@ActivePart = 0 AND Part.Active is not null) 
        OR (@ActivePart = 1 and Part.Active = 0))  
        AND (@ServiceTypes is null 
        OR CHARINDEX(','+cast(SEP.ServiceTypeIDs as varchar(255))+',',','[email protected]+',') > 0)) 
    OR (@ReconciledValue is null and @ActivePart is null and @ServiceTypes is null 
     and (NOT EXISTS (SELECT ServiceEntryID 
         FROM ServiceEntryPart SEP 
         JOIN Part on SEP.PartID = Part.ID))) 
+0

IT STill給了我相同的結果集... – user1475788 2012-07-25 04:39:47

+0

我更新了問題, – user1475788 2012-07-25 04:56:36

+0

好的,如果明天沒有人回答我會再看一眼。睡覺招手。 – Bert 2012-07-25 04:59:18

0

這可能不完全是你想要的,說實話查詢似乎遍佈各地。

您可能正在尋找一個活動部分過濾器,如'(@ActivePart is null或@ActivePart = Part.Active)'。你的存在被內部連接隱含地照顧。下面是一個我相信與您正在尋找的內容接近的查詢。

select * 
FROM ServiceEntry AS S 
INNER JOIN ServiceEntryPart AS SEP ON SEP.ServiceEntryID = S.ServiceEntryID 
INNER JOIN Part AS P ON P.PartID = SEP.PartID 
WHERE S.RunLogEntryID is not null 
    and S.Reconciled = @ReconciledValue 
    and (@ActivePart is null or @ActivePart = Part.Active) 
    and (@ServiceTypes is null or charindex(','+cast(SEP.ServiceTypeIDs as varchar(255))+',',','[email protected]+',') > 0 
+0

我更新了問題 – user1475788 2012-07-25 04:56:48

0

我無法確定,因爲我沒有列的業務定義,但我懷疑處理Part.Active的條件是錯誤的。我期望值爲0或1,而不是NULL或0.所以我應該認爲當參數爲NULL或參數與列匹配時,測試應返回TRUE。

您的CHARINDEX函數具有相反的參數。

您需要額外的括號才能獲得正確的操作順序,而您的OR NOT EXISTS子句需要附加條件才能使參數爲NULL時才爲true。

我相信以下幾點更接近你要找的東西。但我擔心ServiceTypes測試。只有當參數包含一個ServiceTypeID時它才能可靠地工作。如果它包含多個ID,則可能無法正常工作。例如,我認爲參數值'1,3'應該與'1,2,3'列表匹配,但不會。

SELECT * 
    FROM ServiceEntry AS S 
WHERE (S.RunLogEntryID IS NOT NULL) 
    AND ([email protected]) 
    AND(EXISTS(
      SELECT ServiceEntryID 
      FROM ServiceEntryPart SEP 
      JOIN Part ON SEP.PartID = Part.ID 
      WHERE(@ActivePart IS NULL 
        OR @ActivePart = Part.Active 
       ) 
      AND (@ServiceTypes IS NULL 
        OR CHARINDEX(','[email protected]+',', 
           ','+cast(SEP.ServiceTypeIDs as varchar(255))+',' 
           ) > 0 
       ) 
     ) 
     OR(@ActivePart IS NULL 
      AND @ServiceTypes IS NULL 
      AND NOT EXISTS(SELECT ServiceEntryID 
           FROM ServiceEntryPart SEP 
           JOIN Part on SEP.PartID = Part.ID 
         ) 
     ) 
    )