[英]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
子句中支持復合條件,但我想是這樣,這並不是開創性的技術。
更新:
有幾種方法可以做到這一點; 最佳選擇取決於您的數據庫以及不同方法的執行方式。
方法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.