我的SQL中有过滤问题。请看一下数据库的架构。
现在,我希望让熟悉PHP的程序员具备●●●●●●和具有技能的Java●●●。我执行了以下查询:
SELECT p.name, p.city FROM programmers p INNER JOIN skills s
ON p.id = s.programmer
WHERE ( s.lang = 'PHP' AND s.level > 1 ) OR ( s.lang = 'Java' AND s.level = 3 );
我得到的是
但是克里斯托弗并不认识Java,但他还是回来了。在主要条件之间用OR
替换AND
导致没有返回任何内容。
此外,我希望将程序员的所有技能都集中在一起;约书亚分为两排。如何解决?
考虑所有事情,最后一个问题。怎么得到:
希望有可能。提前谢谢。
修改 专注于日期的操作没有问题,也没有必要计算日期之间的差异,SQL只能包含年份,即2010年。通常日期不是重点。
答案 0 :(得分:2)
这是“set-within-sets”问题的一个例子。我喜欢使用聚合和having
:
SELECT p.name, p.city
FROM programmers p INNER JOIN
skills s
ON p.id = s.programmer
GROUP BY p.name, p.city
HAVING SUM( s.lang = 'PHP' AND s.level > 1 ) > 0 AND
SUM( s.lang = 'Java' AND s.level = 3 ) > 0;
编辑:
如果您需要技能列表(不是原始问题的一部分),请使用group_concat()
:
SELECT p.name, p.city, group_concat(s.lang, ':', s.level separator '; ');
FROM programmers p INNER JOIN
skills s
ON p.id = s.programmer
GROUP BY p.name, p.city
HAVING SUM( s.lang = 'PHP' AND s.level > 1 ) > 0 AND
SUM( s.lang = 'Java' AND s.level = 3 ) > 0;
答案 1 :(得分:0)
这会给你你想要的东西,但它根本不灵活。
select p.name, p.city, php.lang, php.level, j.lang, j.level
from programmer p
join skills php
on php.programmer = p.id
join skills j
on j.programmer = p.id
where php.lang = 'PHP' and php.level > 1
and j.lang = 'Java' and j.level = 3;
如果您要进行大量此类查询,可以考虑为每个技能集创建一个视图:
create view JavaSkills as
select programmer, lang, level, exp_from
from skills
where lang = 'Java'
然后查询
select p.name, p.city, php.lang, php.level, j.lang, j.level
from programmer p
join PhpSkills php
on php.programmer = p.id
join JavaSkills j
on j.programmer = p.id
where php.level > 1
and j.level = 3;
执行计划应该是相似的,如果不相同但查询更容易阅读。维护起来也很尴尬,但人们可以做到。 ;)