簡體   English   中英

左外連接使用 Where 從右表中排除記錄

[英]Left Outer Join Using Where to Exclude Records from the Right Table

使用 Sql Server 2008。我們完成了工作表。 通常對於任何客戶,作業#1 之后是作業#2,然后是作業#3。

CustNum, JobDate, TypeJob
100,   4/10/2019, 2
100,   4/11/2019, 1
100,   4/12/2019, 2
100,   4/13/2019, 3
100,   4/13/2019, 3
222,   4/10/2019, 2
222,   4/11/2019, 1
333,   4/11/2019, 2
444,   3/1/2019,  3
444,   4/10/2019, 1
444,   4/11/2019, 2

我正在尋找所有工作#2 且日期 > 工作#1(兩者都存在)但之后未輸入工作#3 的客戶。

  • 客戶 100 很好,作業 1、2、3 全部按日期順序完成。 我不想要客戶 100。
  • 客戶 222 在工作#1 之后沒有工作#2,所以我也不想要那個。
  • 客戶 333 沒有任何工作#1,所以我不想要那個。
  • 客戶 444 是我正在尋找的客戶。

這是我所做的,它有效,但看起來很笨拙。

Select
  L.CustNum, 
  L.JobDate1, 
  L.JobDate2,
  R.JobDate3
From
(
    --A<B has JobDate1 followed by JobDate2
    Select 
      First.CustNum as [CustNum], 
      First.JobDate as JobDate1,
      Second.JobDate as JobDate2
    From
    (
        Select [CustNum], Max([JobDate]) as JobDate From tbJobs
        Where [TypeJob] = 1
        Group by CustNum
    ) First
    Join
    (
        Select [CustNum], Max([JobDate]) as JobDate From tbJobs
        Where [TypeJob] = 2
        Group by CustNum
    ) Second
    On First.CustNum = Second.CustNum
    Where Second.JobDate > First.JobDate
) L
Left Outer Join
(
    --A<B #and# C>A has JobDate1 followed by JobDate2 and JobDate3
    Select 
      First.CustNum as [CustNum], 
      --First.JobDate as JobDate1,
      --Second.JobDate as JobDate2,
      Third.JobDate as JobDate3
    From
    (
        Select [CustNum], Max([JobDate]) as JobDate From tbJobs 
        Where [TypeJob] = 1
        Group by CustNum
    ) First
    Join
    (
        Select [CustNum], Max([JobDate]) as JobDate From tbJobs
        Where [TypeJob] = 2
        Group by CustNum
    ) Second
    On First.CustNum = Second.CustNum
    Join
    (
        Select [CustNum], Max([JobDate]) as JobDate From tbJobs
        Where [TypeJob] = 3
        Group by CustNum
    ) Third
    On Second.CustNum = Third.CustNum
    Where Third.JobDate > First.JobDate
    And Second.JobDate > First.JobDate
) R
On First.CustNum = Third.CustNum
Where JobDate3 is null
Order by CustNum

我真正想做的是這樣的:

Select ... From
(Select ...) First
Join
(Select ...) Second
Left Outer Join
(Select ...) Third
On ...
Where Second.JobDate > First.JobDate 
    And (Third.JobDate > First.JobDate) is null

我將如何(是否可能)制定 Where 語句,以便它忽略任何 Third.JobDate <= First.JobDate 並且只找到 Third.JobDate(大於 First.JobDate)為 null 的行?

使用 Sql 服務器 2008。

一個簡單的聚合查詢應該在這里工作:

WITH cte AS (
    SELECT
        CustNum,
        MAX(CASE WHEN TypeJob = 1 THEN JobDate END) AS date1,
        MAX(CASE WHEN TypeJob = 2 THEN JobDate END) AS date2,
        MAX(CASE WHEN TypeJob = 3 THEN JobDate END) AS date3
    FROM tbJobs
    GROUP BY CustNum
)

SELECT CustNum
FROM cte
WHERE
    COALESCE(date2, date1) > COALESCE(date1, date2) AND
    (date3 < date2 OR date3 IS NULL);

HAVING子句中使用COALESCE可確保客戶只有在第一個和第二個日期都存在時才能通過。

使用公用表表達式:

;WITH First AS (
SELECT CustNum, MAX(JobDate) JobDate1
  FROM tbJobs
 WHERE TypeJob = 1
 GROUP BY CustNum
), Second AS (
SELECT CustNum, MAX(JobDate) JobDate2
  FROM tbJobs
 WHERE TypeJob = 2
 GROUP BY CustNum
), Third AS (
SELECT CustNum, MAX(JobDate) JobDate3
  FROM tbJobs
 WHERE TypeJob = 3
 GROUP BY CustNum
)
SELECT f.CustNum, JobDate1, JobDate2, JobDate3
  FROM First f
 INNER JOIN Second s ON f.CustNum = s.CustNum AND f.JobDate1 < s.JobDate2
  LEFT JOIN Third t ON s.CustNum = t.CustNum AND s.JobDate2 < t.JobDate3
 WHERE JobDate3 IS NULL

暫無
暫無

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

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