SQL中的高级过滤器

时间:2014-12-02 16:03:22

标签: mysql sql database database-schema

我的SQL中有过滤问题。请看一下数据库的架构。

enter image description here

现在,我希望让熟悉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 = 3)
  • 约书亚,亚特兰大(因为PHP> 1)
  • 克里斯托弗,芝加哥(因为PHP> 1)

但是克里斯托弗并不认识Java,但他还是回来了。在主要条件之间用OR替换AND导致没有返回任何内容。

此外,我希望将程序员的所有技能都集中在一起;约书亚分为两排。如何解决?

考虑所有事情,最后一个问题。怎么得到:

  • 具有PHP●●●●●●,JS●●●和HTML●/●●/●●●
  • 技能的程序员
  • 具有PHP●●/●●●和PHP经验2年以上的程序员和具有4年以上经验的JS●●●
  • 具有PHP●/●●/●●●和JS●●●技能的程序员,两年以上经验至少3年以上

希望有可能。提前谢谢。


修改 专注于日期的操作没有问题,也没有必要计算日期之间的差异,SQL只能包含年份,即2010年。通常日期不是重点。

2 个答案:

答案 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;

执行计划应该是相似的,如果不相同但查询更容易阅读。维护起来也很尴尬,但人们可以做到。 ;)