簡體   English   中英

如何根據第二張表的狀態執行條件SQL左聯接?

[英]How do you do a condition SQL left join based on the status of the second table?

例如,我有兩個表

Person Table
ID : Name
1 : Bob
2 : Jane
3 : Mike
4 : John
5: Mary

然后,我也有了(current實際上是一個整數,但是我使用文本使其更具可讀性):

Job Table
ID : Name : PersonID : JobStatus
1 : Plumber : 1 : current
2 : Doctor : 2 : past
3 : Driver : 2 : current
4 : Cook : 3 : current
5: Programmer : 5 : past

我想加入兩個表,以便獲得每個人的列表,但是我只想用左聯接包括當前作業。 換句話說,我希望結果是:

Bob : Plumber : current
Jane : Driver : current
Mike : Cook : current
John : :  
Mary : : 

我該如何加入聯接。 我試着做:

SELECT 
  person.name, job.name, job.status 
FROM 
  person
LEFT JOIN 
  job ON person.id=job.person.id

但是問題在於,在這種情況下,我將看到Jane的兩個條目,一個是她過去的Doctor職位以及她的Driver的新職位。 如果我添加了where子句,例如:

WHERE job.status='current' 

然后從列表中刪除John和Mary。

我該如何編寫一個聯接,以顯示所有人員,但只包括當前的工作?

至少在Oracle中,您應該能夠做到這一點:

SELECT 
  person.name, job.name, job.status 
FROM 
  person
LEFT JOIN 
   job ON person.id=job.personId AND job.status = 'current';

因此,當person.id=job.person.id AND job.status = 'current'person.id=job.person.id AND job.status = 'current' ,並且當該條件為false時,您僅會獲得person數據。

我不知道MySQL是否在ON子句中支持復合條件,但我想是這樣,這並不是開創性的技術。

更新:

看起來受支持,請閱讀https://dev.mysql.com/doc/refman/8.0/en/join.html

有幾種方法可以做到這一點; 最佳選擇取決於您的數據庫以及不同方法的執行方式。

方法1:左聯接或

SELECT p.name, j.name, j.status
FROM person AS p
LEFT JOIN job AS j ON j.personId = p.id AND j.status = 'current';
-- Returns all persons, and only jobs w/ value 'current'
-- If the filter on j.status were in the WHERE clause, it would remove non-matching

方法2:使用UNION ALL執行兩個查詢(這將刪除沒有當前值或空值的行)

SELECT p.name, j.name, j.status
FROM person AS p
INNER JOIN job AS j ON j.personId = p.id
WHERE j.status = 'current'
OR j.status IS NULL

UNION ALL

SELECT p.name, j.name, j.status
FROM person AS p
LEFT JOIN job AS j ON j.personId = p.id
WHERE j.status IS NULL;

方法2b:使用UNION ALL執行兩個查詢(這將保留沒有當前值或空值的行)

SELECT p.name, j.name, j.status
FROM person AS p
INNER JOIN job AS j ON j.personId = p.id
WHERE j.status = 'current'
OR j.status IS NULL

UNION ALL

SELECT p.name, j.name, j.status
FROM person AS p
LEFT JOIN job AS j ON j.personId = p.id
WHERE NOT EXISTS 
  (SELECT 1 FROM jobs AS t WHERE t.personId=p.Id AND t.status='current')
GROUP BY p.Id; 
-- GROUP BY ensures we only get one row back per person, but will be random if there are multiples

方法3:子選擇

SELECT p.name, j.name, j.status
FROM person AS p
LEFT JOIN (
  SELECT x.name
  FROM job AS x
  WHERE x.status = 'current'
) AS j;
   Select p.name, j.name,j.status 
     From person p 
Left Join
         (Select name,status,personId 
            From job 
            Where status ='current'
         ) j On p.id = j.personId;

你可以試試這個查詢嗎?

嘗試這個

SELECT 
  person.name, job.name, job.status 
FROM 
  person
LEFT JOIN 
  job ON person.id=job.person.id
WHERE CASE WHEN job.status IS NULL THEN '@' WHEN job.status ='current' THEN '@' else job.status END = '@'

暫無
暫無

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

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