例如,我有两个表
Person Table
ID : Name
1 : Bob
2 : Jane
3 : Mike
4 : John
5: Mary
然后我也有(当前实际上是一个整数,但我使用文本使其更具可读性):
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。
如何编写一个可以显示所有人员但只包括当前职位的联接?
答案 0 :(得分:2)
至少在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'
联接时,并且当该条件为false时,您仅会获得person
数据。
我不知道MySQL是否在ON
子句中支持复合条件,但我想是这样,这并不是开创性的技术。
更新:
答案 1 :(得分:0)
有几种方法可以做到这一点;最佳选择取决于您的数据库以及不同方法的执行方式。
方法1:使用OR左联接
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;
答案 2 :(得分:0)
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;
您可以尝试查询吗?
答案 3 :(得分:0)
尝试一下
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 = '@'