簡體   English   中英

如果兩列值不相同則過濾行-SQL Server

[英]Filtering rows if two columns values are not same - sql server

我需要在OwningOfficeID和ScopeOfficeID不相同的行上應用日期過濾器。

這是主要查詢;

SELECT distinct v.VisitID, a.OfficeID AS OwningOfficeID, 
       scp.OfficeID AS ScopeOfficeID, V.VisitDate, 
       a.staffID as OwningStaff ,scp.StaffID as OwningScope
 FROM Visits v 
    INNER JOIN VisitDocs  vdoc ON vdoc.VisitID = v.VisitID 
    INNER JOIN InspectionScope scp ON scp.ScopeID = v.ScopeID 
    INNER JOIN Assignments a ON a.AssignmentID = scp.AssignmentID 
    INNER JOIN Staff s ON s.StaffID = a.StaffID
 WHERE 
  v.VisitType = 1  AND
 --'SCOPE OWNER AND LOOK FOR INSPECTION REPORT BUT NOT FOR COORD/FINAL REPORT.
     (scp.StaffID = 141
        AND EXISTS(SELECT *           
                     FROM VisitDocs d          
                    WHERE d.VisitID = v.VisitID          
                      AND d.docType = 13)          
        AND NOT EXISTS(SELECT * 
                         FROM VisitDocs d  
                        WHERE d.VisitID = v.VisitID  AND d.docType IN (1,2))
     )
     OR 
--'ASSIGNMENT OWNER AND NOT SCOPE OWNER AND LOOK FOR COORDINATOR REPORT. 
(a.StaffID = 141 AND scp.StaffID != 141
 AND EXISTS(SELECT *           
                 FROM VisitDocs d          
                 WHERE d.VisitID = v.VisitID          
                 AND d.docType = 2)          
 AND NOT EXISTS(SELECT * FROM VisitDocs d  
                 WHERE d.VisitID = v.VisitID  AND d.docType IN (1))
 )

結果集

在此處輸入圖片說明

可以將以下條件應用於外部選擇查詢以實現結果。

(OwningOfficeID <> ScopeOfficeID和VisitDate> ='01/11/2012'或OwningOfficeID = ScopeOfficeID)

無論如何,在一個select語句中有做嗎?

我不確定一個select語句的含義,但我認為您真正想知道的是如何執行此查詢,以使其快速運行,容易看到並且正確且易於維護。

這是怎么做的; 使用CTE。 (如果您不知道CTE是什么,請先閱讀它們,然后再返回此處-它們已記錄在Microsoft網站上。)

CTE可以比子查詢更快,更清晰。 讓我向您展示如何使用上面的代碼並使用CTE進行重構:

WITH DocTypes AS 
(
   SELECT VisitID, docType
   FROM VisitDocs
), DocType13 AS
(
   SELECT VisitID
   FROM DocTypes 
   WHERE docType = 13
), DocType1and2 AS
(
   SELECT VisitID
   FROM DocTypes 
   WHERE docType IN (1,2)
), DocType1 AS
(
   SELECT VisitID
   FROM DocTypes1and2 
   WHERE docType = 1
), DocType2 AS
(
   SELECT VisitID
   FROM DocTypes1and2 
   WHERE docType = 2
), Base AS
(
  SELECT distinct v.VisitID, a.OfficeID AS OwningOfficeID, 
         scp.OfficeID AS ScopeOfficeID, V.VisitDate, 
         a.staffID as OwningStaff ,scp.StaffID as OwningScope
   FROM Visits v 
      INNER JOIN VisitDocs  vdoc ON vdoc.VisitID = v.VisitID 
      INNER JOIN InspectionScope scp ON scp.ScopeID = v.ScopeID 
      INNER JOIN Assignments a ON a.AssignmentID = scp.AssignmentID 
      INNER JOIN Staff s ON s.StaffID = a.StaffID
   WHERE 
    v.VisitType = 1  AND
   --'SCOPE OWNER AND LOOK FOR INSPECTION REPORT BUT NOT FOR COORD/FINAL REPORT.
       (scp.StaffID = 141
          AND EXISTS(SELECT * FROM DocType13 d WHERE d.VisitID = v.VisitID)          
          AND NOT EXISTS(SELECT * FROM DocType1and2 d WHERE d.VisitID = v.VisitID)
       )
       OR 
  --'ASSIGNMENT OWNER AND NOT SCOPE OWNER AND LOOK FOR COORDINATOR REPORT. 
  (a.StaffID = 141 AND scp.StaffID != 141
    AND EXISTS(SELECT * FROM DocType2 d WHERE d.VisitID = v.VisitID)          
    AND NOT EXISTS(SELECT * FROM DocType1 d WHERE d.VisitID = v.VisitID)
  )
)
SELECT *
FROM Base
WHERE (OwningOfficeID <> ScopeOfficeID 
      AND VisitDate >='01/11/2012'( 
      OR OwningOfficeID = ScopeOfficeID 

應該清楚為什么會更好,但是如果不是短暫的話:

  • 您在開始時看到的所有選擇都與原始查詢中的選擇完全相同,但是由於在優化器擁有更輕松時間之前就已將它們分解,因此與子查詢相比,它會做得更好-我已經看到了巨大的選擇在某些情況下會發生變化,但無論如何,優化器現在可以選擇更好地執行內存緩存等操作。

  • 它更清晰,更容易測試。 如果查詢有問題,可以進行簡單測試,將主要選擇注釋掉,然后選擇一個子查詢,這是您期望的嗎? 這些子查詢很簡單,但是會變得很復雜,這使它變得更容易。

  • 您說您想對該查詢應用一些邏輯。 我已將其添加到CTE中,如您所見,它使此復雜的“分層”變得簡單。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM