如何避免 MySQL 子查询中的列重复?
How to avoid repetitions of columns in MySQL subquery?
我正在使用以下查询
从上面 4 table 中检索结果
SELECT
(SELECT SUM(CASE when c.Training_Id=1 then 1 else 0 end)
FROM courses c
INNER JOIN enrolled_students es
ON c.Course_Id = es.Course_Id
) STEM,
(SELECT SUM(CASE when c.Training_Id=2 then 1 else 0 end)
FROM courses c
INNER JOIN enrolled_students es ON c.Course_Id = es.Course_Id
) MA,
c.* FROM campus c;
此查询的问题是,两 (2) 名学生在 STEM 中,一 (1) 名学生在 MA 中反对 Campus_Id 3,但它针对所有校区重复记录。我想如果校园里没有学生,那么应该有 '0' 零。
您需要按 Campus_Id
过滤您的子选择。但首先你必须使用不同的 table 别名。将最后一行更改为 ca.* FROM campus ca
。然后您可以在子选择中使用 where 子句 (WHERE c.Campus_Id = ca.Campus_Id
).
SELECT
(SELECT SUM(CASE when c.Training_Id=1 then 1 else 0 end)
FROM courses c
INNER JOIN enrolled_students es
ON c.Course_Id = es.Course_Id
WHERE c.Campus_Id = ca.Campus_Id -- line added
) STEM,
(SELECT SUM(CASE when c.Training_Id=2 then 1 else 0 end)
FROM courses c
INNER JOIN enrolled_students es ON c.Course_Id = es.Course_Id
WHERE c.Campus_Id = ca.Campus_Id -- line added
) MA,
ca.* FROM campus ca; -- line changed
这应该可以解决您的问题。
要提高性能,您还可以通过 Training_Id
过滤子选择。在第一个子选择中,您只需要带有 Training_Id=1
的行。因此,您可以将 where 子句更改为:
WHERE c.Campus_Id = ca.Campus_Id
AND c.Training_Id = 1
这样做你也可以使用 COUNT
而不是 SUM
。所以你的子选择看起来像:
SELECT COUNT(1)
FROM courses c
INNER JOIN enrolled_students es ON c.Course_Id = es.Course_Id
WHERE c.Campus_Id = ca.Campus_Id AND c.Training_Id = 1
为了防止代码重复(您的子选择几乎相等),您可以加入所有需要的 table 并按 Campus_Id
:
分组
select
COUNT(co.Training_Id=1 OR NULL) STEM,
COUNT(co.Training_Id=2 OR NULL) MA,
ca.Campus_Id
from campus ca
left join courses co on co.Campus_Id = ca.Campus_Id
left join enrolled_students es on es.Course_Id = co.Course_Id
where co.Training_Id in (1, 2)
group by ca.Campus_Id
我正在使用以下查询
从上面 4 table 中检索结果SELECT
(SELECT SUM(CASE when c.Training_Id=1 then 1 else 0 end)
FROM courses c
INNER JOIN enrolled_students es
ON c.Course_Id = es.Course_Id
) STEM,
(SELECT SUM(CASE when c.Training_Id=2 then 1 else 0 end)
FROM courses c
INNER JOIN enrolled_students es ON c.Course_Id = es.Course_Id
) MA,
c.* FROM campus c;
此查询的问题是,两 (2) 名学生在 STEM 中,一 (1) 名学生在 MA 中反对 Campus_Id 3,但它针对所有校区重复记录。我想如果校园里没有学生,那么应该有 '0' 零。
您需要按 Campus_Id
过滤您的子选择。但首先你必须使用不同的 table 别名。将最后一行更改为 ca.* FROM campus ca
。然后您可以在子选择中使用 where 子句 (WHERE c.Campus_Id = ca.Campus_Id
).
SELECT
(SELECT SUM(CASE when c.Training_Id=1 then 1 else 0 end)
FROM courses c
INNER JOIN enrolled_students es
ON c.Course_Id = es.Course_Id
WHERE c.Campus_Id = ca.Campus_Id -- line added
) STEM,
(SELECT SUM(CASE when c.Training_Id=2 then 1 else 0 end)
FROM courses c
INNER JOIN enrolled_students es ON c.Course_Id = es.Course_Id
WHERE c.Campus_Id = ca.Campus_Id -- line added
) MA,
ca.* FROM campus ca; -- line changed
这应该可以解决您的问题。
要提高性能,您还可以通过 Training_Id
过滤子选择。在第一个子选择中,您只需要带有 Training_Id=1
的行。因此,您可以将 where 子句更改为:
WHERE c.Campus_Id = ca.Campus_Id
AND c.Training_Id = 1
这样做你也可以使用 COUNT
而不是 SUM
。所以你的子选择看起来像:
SELECT COUNT(1)
FROM courses c
INNER JOIN enrolled_students es ON c.Course_Id = es.Course_Id
WHERE c.Campus_Id = ca.Campus_Id AND c.Training_Id = 1
为了防止代码重复(您的子选择几乎相等),您可以加入所有需要的 table 并按 Campus_Id
:
select
COUNT(co.Training_Id=1 OR NULL) STEM,
COUNT(co.Training_Id=2 OR NULL) MA,
ca.Campus_Id
from campus ca
left join courses co on co.Campus_Id = ca.Campus_Id
left join enrolled_students es on es.Course_Id = co.Course_Id
where co.Training_Id in (1, 2)
group by ca.Campus_Id