如何根据第二个表的状态执行条件sql left join?

nhhxz33t  于 2021-06-24  发布在  Mysql
关注(0)|答案(4)|浏览(269)

比如我有两张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 : :

我怎么能用join来做呢。我试着做:

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

但问题是,在这种情况下,我会看到简的两个条目,一个是她过去的医生工作,另一个是她的新司机工作。如果我加上where子句,比如:

WHERE job.status='current'

然后就把约翰和玛丽从名单上删除了。
如何编写一个join来显示所有人,但只包含当前的工作?

hs1ihplo

hs1ihplo1#

至少在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 但我想是的,这并不是什么突破性的技术。
更新:
看起来它是受支持的,请阅读https://dev.mysql.com/doc/refman/8.0/en/join.html

biswetbf

biswetbf2#

试试这个

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 = '@'
s8vozzvw

s8vozzvw3#

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;

你能试试这个查询吗?

kognpnkq

kognpnkq4#

有几种方法可以做到这一点;最佳选择取决于您的数据库以及不同方法的执行方式。
方法一:用或左连接

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的两个查询(这将删除没有当前VAL或空VAL的行)

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的两个查询(这将保留没有当前VAL或空VAL的行)

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;

相关问题