对没有相同列的行组执行联合。尝试生成空的直方图 bin
Performing a Union on groups of rows without the same columns. Trying to generate empty histogram bins
我正在使用 MySQL。
我有一个 table grades
,看起来像这样:
course_id grade
101 90
101 100
101 100
102 92
102 85
102 90
我有一个视图,使用以下查询计算每个箱子中有多少个等级,每个 class。
SELECT
*,
COUNT(grade_bin) as count
FROM
(SELECT
course_id,
FLOOR(grade/5.00)*5 AS grade_bin
FROM ranked_grades) as t
GROUP BY course_id, grade_bin
ORDER BY course_id, grade_bin ASC;
这个returns:
course_id grade_bin count
101 90 1
101 100 2
102 85 1
102 90 2
我想向此视图添加空容器,如下所示:
course_id grade_bin count
101 40 0
101 45 0
... ... ...
101 100 2
102 40 0
... ... ...
所以 bins 递增 5,从 40 开始,到 100 停止。我的想法是为空 bins 做一个 table,插入每个等级 bin 和计数 0,然后使用 UNION
但我无法让 UNION
工作,因为我在空箱 table 中没有 course_id
列(我也不想 - 有一个很多,他们可能会改变)。我如何为每组 course_ids
做一个联合?
从垃圾箱列表开始。然后使用 cross join
生成所有行。最后加入已有的数据。
所以:
SELECT c.course_id, gb.grade_bin, COUNT(rg.course_id) as cnt
FROM (SELECT 40 as grade_bin UNION ALL
SELECT 45 as grade_bin UNION ALL
SELECT 50 as grade_bin UNION ALL
. . .
SELECT 100 as grade_bin
) gb CROSS JOIN
(SELECT DISTINCT course_id
FROM ranked_grades
) c LEFT JOIN
ranked_grades rg
ON rg.course_id = c.course_id AND
rg.grade >= gb.grade_bin AND
rg.grade < gb.grade_bin + 5
GROUP BY c.course_id, gb.grade_bin;
注意:这将从 ranked_grades
table 中检索课程。您也可以使用 courses
table 大概也可用。
假设您创建的 table bin_table
只有 1 列 grade_bin
和值 40, 45, 50, ...., 100 并且您有一个table cources
以列 course_id
作为主键,您所要做的就是 CROSS
加入这些 table 和 LEFT
加入一个在 table ranked_grades
上聚合的查询(不需要子查询):
SELECT c.course_id, b.grade_bin, COALESCE(t.count, 0) AS count
FROM bin_table b CROSS JOIN cources c
LEFT JOIN (
SELECT course_id, FLOOR(grade / 5.00) * 5 AS grade_bin, COUNT(*) AS count
FROM ranked_grades
GROUP BY course_id, grade_bin
) t ON (t.course_id, t.grade_bin) = (c.course_id, b.grade_bin)
我正在使用 MySQL。
我有一个 table grades
,看起来像这样:
course_id grade
101 90
101 100
101 100
102 92
102 85
102 90
我有一个视图,使用以下查询计算每个箱子中有多少个等级,每个 class。
SELECT
*,
COUNT(grade_bin) as count
FROM
(SELECT
course_id,
FLOOR(grade/5.00)*5 AS grade_bin
FROM ranked_grades) as t
GROUP BY course_id, grade_bin
ORDER BY course_id, grade_bin ASC;
这个returns:
course_id grade_bin count
101 90 1
101 100 2
102 85 1
102 90 2
我想向此视图添加空容器,如下所示:
course_id grade_bin count
101 40 0
101 45 0
... ... ...
101 100 2
102 40 0
... ... ...
所以 bins 递增 5,从 40 开始,到 100 停止。我的想法是为空 bins 做一个 table,插入每个等级 bin 和计数 0,然后使用 UNION
但我无法让 UNION
工作,因为我在空箱 table 中没有 course_id
列(我也不想 - 有一个很多,他们可能会改变)。我如何为每组 course_ids
做一个联合?
从垃圾箱列表开始。然后使用 cross join
生成所有行。最后加入已有的数据。
所以:
SELECT c.course_id, gb.grade_bin, COUNT(rg.course_id) as cnt
FROM (SELECT 40 as grade_bin UNION ALL
SELECT 45 as grade_bin UNION ALL
SELECT 50 as grade_bin UNION ALL
. . .
SELECT 100 as grade_bin
) gb CROSS JOIN
(SELECT DISTINCT course_id
FROM ranked_grades
) c LEFT JOIN
ranked_grades rg
ON rg.course_id = c.course_id AND
rg.grade >= gb.grade_bin AND
rg.grade < gb.grade_bin + 5
GROUP BY c.course_id, gb.grade_bin;
注意:这将从 ranked_grades
table 中检索课程。您也可以使用 courses
table 大概也可用。
假设您创建的 table bin_table
只有 1 列 grade_bin
和值 40, 45, 50, ...., 100 并且您有一个table cources
以列 course_id
作为主键,您所要做的就是 CROSS
加入这些 table 和 LEFT
加入一个在 table ranked_grades
上聚合的查询(不需要子查询):
SELECT c.course_id, b.grade_bin, COALESCE(t.count, 0) AS count
FROM bin_table b CROSS JOIN cources c
LEFT JOIN (
SELECT course_id, FLOOR(grade / 5.00) * 5 AS grade_bin, COUNT(*) AS count
FROM ranked_grades
GROUP BY course_id, grade_bin
) t ON (t.course_id, t.grade_bin) = (c.course_id, b.grade_bin)