对不起标题。我现在不能带任何有意义的东西来,但如果你有什么建议,我会更新的。
好吧,这个问题已经困扰我好几天了,快把我逼疯了。
我有一个数据库,保存与教育相关的过滤器。

table: FILTERS

filterid filtertype value
1        school     MIT
1        school     UT
1        school     Lund
1        major      econ
1        major      civil
1        graduate   1
2        school     Harvard

这里我定义了两个过滤器,1和2。如果学校是(麻省理工学院、犹他大学或隆德大学)之一,专业是(经济或民用)之一,并且是研究生课程,则教育记录通过筛选1。
为了通过2级考试,一个教育记录只需要有哈佛作为学校。
我有另一个表,保存用户的教育记录。用户可以有多个教育记录(例如,一个用于本科学习,一个用于研究生)
table: EDUCATION
educid uid    school   major   graduate
1      1      MIT      econ    1
2      1      Lund     cs      0

所以第一个人有两个教育记录。
这里的教育记录1通过了过滤器1,因为学校(MIT)属于集合{MIT,UT,Lund),专业(econ)属于集合{econ,civil},是一个研究生课程。然而,教育记录1没有通过筛选2,因为学校是麻省理工学院,而不是哈佛大学。
教育记录2不通过筛选1,因为专业(cs)不在{econ,civil}中,并且它不通过筛选2,因为学校是Lund,而不是harvard。
如果个人1的教育记录都不通过筛选器1,则她不会通过筛选器1。
因此,人1通过过滤器1(因为她的第一个教育记录通过过滤器1),但不通过过滤器2,因为她所有的教育记录都不通过过滤器2。
我的目标是选择第1个人不通过的过滤器的filterid。
这就是我到目前为止所做的:
SELECT filterid FROM filters
LEFT JOIN education ON education.uid=1 AND (
(filtertype='school' AND filters.value=education.school) OR
(filtertype='major' AND filters.value=education.major) OR
(filtertype='graduate' AND filters.value=education.graduate)
)
GROUP BY filterid
HAVING ( SUM(educid IS NULL)>0 )

这显然不起作用,因为根据此查询,如果某人的某个教育记录不通过筛选器1,则此人1不会通过筛选器1。(如果她的记录都没有通过过滤器1,则应该是这样)。
我真的很感激任何解决方案,因为它真的让我困惑。

最佳答案

一种方法

SELECT f.filterid
  FROM filters f
  LEFT JOIN education e1
    ON e1.uid = 1
   AND f.filtertype = 'school'
   AND f.value = e1.school
  LEFT JOIN education e2
    ON e2.uid = 1
   AND f.filtertype = 'major'
   AND f.value = e2.major
  LEFT JOIN education e3
    ON e3.uid = 1
   AND f.filtertype = 'graduate'
   AND f.value = e3.graduate
 GROUP BY f.filterid
HAVING MAX(e1.educid IS NOT NULL) +
       MAX(e2.educid IS NOT NULL) +
       MAX(e3.educid IS NOT NULL) < 3


SELECT f.filterid
  FROM filters f LEFT JOIN
(
  SELECT uid, educid, 'school' type, school value
    FROM education
   WHERE uid = 1
  UNION ALL
  SELECT uid, educid, 'major' type, major value
    FROM education
   WHERE uid = 1
  UNION ALL
  SELECT uid, educid, 'graduate' type, graduate value
    FROM education
   WHERE uid = 1
) e
    ON f.filtertype = e.type
   AND f.value = e.value
 GROUP BY f.filterid
HAVING MAX(f.filtertype = 'school' AND e.educid IS NOT NULL) +
       MAX(f.filtertype = 'major' AND e.educid IS NOT NULL) +
       MAX(f.filtertype = 'graduate' AND e.educid IS NOT NULL) < 3;

这里是SQLFiddle演示

10-06 08:47