从右表条件获取左表行
Posted
技术标签:
【中文标题】从右表条件获取左表行【英文标题】:get left table rows from right table conditions 【发布时间】:2019-05-09 13:36:29 【问题描述】:我有三个这样的表:
人:
编号 |姓名 |性别 -------------------------- 1乔男 2 丹尼尔男 3 莎拉女person_skills:
人名 |技能ID -------------------------- 1 1 1 2 1 3 2 1 2 2 ...技能:
编号 |技能名称 ---------------------- 1 写作 2 编程 3 唱歌 ...当我只在我的查询中发送他们的一项技能时,我需要获取他们的所有技能。
这是我的代码:
SELECT a.name, a.gender,
GROUP_CONCAT(DISTINCT c.skill_name),
GROUP_CONCAT(DISTINCT c.id as skill_id)
FROM persons a
LEFT JOIN person_skills b ON b.person_id = a.id
LEFT JOIN skills c ON c.id = b.skill_id
WHERE b.skill_id = 3 GROUP BY a.id
我想要结果:
姓名 |性别 |技能名 |技能ID ---------------------------------------------- 乔男写作 1 编程 2 唱歌 3但是这段代码只返回skill_id“3”和skill_name“Singing”。
提前致谢。
【问题讨论】:
您的 SQL 甚至没有意义,因为它引用了不存在的列...但同样,您是否要问:“我如何获得所有技能的列表有“唱歌”技能的人吗? 忽略错别字,您需要引用person_skills
两次;首先获得技能 3 的人,然后再获得这些人的技能。
把你的 WHERE 子句改成WHERE a.id = (SELECT b.person_id FROM person_skills WHERE skill_id = 3)
,我想你会得到你想要的。
@Uueerdo 是的,我试过了,效果很好。但我正在寻找一种更快的方法。
@Jake 不太可能有更快的方法,除非您的做法与我假设的不同(例如,请参阅我的答案)。更多的表引用并不一定等于更慢。
【参考方案1】:
您需要引用一些表两次。
SELECT p.name, p.gender,
GROUP_CONCAT(DISTINCT s.skill_name),
GROUP_CONCAT(DISTINCT s.id as skill_id)
FROM person_skills AS ps0
INNER JOIN persons AS p ON ps0.person_id = p.id
LEFT JOIN person_skills ps ON p.id = ps.person_id
LEFT JOIN skills s ON s.id = ps.skill_id
WHERE ps0.skill_id = 3
GROUP BY p.id
旁注:我没有处理它,但您的分组标准在某些配置下可能会出现问题。
...如果您不喜欢额外的表引用,但不太可能更快的是:
SELECT p.name, p.gender,
GROUP_CONCAT(DISTINCT s.skill_name),
GROUP_CONCAT(DISTINCT s.id as skill_id)
FROM persons AS p
LEFT JOIN person_skills ps ON p.id = ps.person_id
LEFT JOIN skills s ON s.id = ps.skill_id
GROUP BY p.id
HAVING COUNT(CASE s.skill_id WHEN 3 THEN 1 ELSE NULL) > 0;
【讨论】:
谢谢。我想我应该使用你的第一种方法。 是的,第二种方法基本上是为大家收集信息,然后在做完所有工作后消除不需要的数据。对于非常小的数据集,它在技术上可能更快,但在这些情况下,速度差异通常是微不足道的。以上是关于从右表条件获取左表行的主要内容,如果未能解决你的问题,请参考以下文章