我遇到了获取数据的问题。我想找到所有课程,其中包含where子句中的标志,并获得它包含的所有标志课程。
课程表的记录:
+----+----------+
| id | name |
+----+----------+
| 1 | Spring |
| 2 | Hibernate|
| 3 | C# |
+----+----------+
course_flags 表的记录:
+----+----------+----------+
| id |course_id | flag_id |
+----+----------+----------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 1 |
+----+----------+----------+
标志表的记录:
+----+------------+
| id | name |
+----+------------+
| 1 | promocja |
| 2 |last minute |
+----+------------+
我的查询
SELECT course.id, course.name,
GROUP_CONCAT(Flag.id SEPARATOR ',') as flags
FROM course
INNER JOIN course_flags ON
course.id = course_flags.course_id
INNER JOIN flag ON
flag.id = course_flags.flag_id
WHERE flag.name LIKE 'promocja'
GROUP BY Course.id
不幸的是,我的数据库引擎在 flags 列中返回了带有一个标记的记录:
+----+----------+----------+
| id | name | flags |
+----+----------+----------+
| 1 | Spring | 1 |
| 2 | Hibernate| 1 |
+----+----------+----------+
我原本希望得到这个结果:
+----+----------+----------+
| id | name | flags |
+----+----------+----------+
| 1 | Spring | 1,2 |
| 2 | Hibernate| 1 |
+----+----------+----------+
问我怎么得到它?
提前致谢!
答案 0 :(得分:2)
WHERE
子句将记录之前的限制为分组;而HAVING
子句在分组后限制结果:
SELECT course.id, course.name, GROUP_CONCAT(Flag.id) flags
FROM course
JOIN course_flags ON course_flags.course_id = course.id
JOIN flag ON flag.id = course_flags.flag_id
GROUP BY Course.id
HAVING SUM(flag.name = 'promocja')
在sqlfiddle上查看。
答案 1 :(得分:2)
简单地使用这样的连接的问题是你的WHERE
子句将减少结果集可用的标志。你真正需要做的是使用一个子选择来首先确定具有这个标志的id,然后使用那组id,确定每个id的标志。可能看起来像这样:
SELECT
c.id AS id,
c.name AS name,
GROUP_CONCAT(cf.flag_id) AS flags
FROM course AS c
INNER JOIN course_flag AS cf
ON c.id = cf.course_id
INNER JOIN
(SELECT cf2.course_id AS id
FROM course_flags AS cf2
INNER JOIN flag AS f
WHERE f.name = ?) AS ids
ON c.id = ids.id
GROUP BY c.id
?
是您要查询的标志名称。注意我在=
子句中使用了WHERE
而不是LIKE
,因为您甚至没有使用LIKE
功能(您没有通配符)。