我正在尝试使用MySQL获得大于其他表中某些值的条目数。
我有与这些表类似的表(但更大):
CREATE TABLE test_ranges AS SELECT 'class 1' AS category, 'A' AS grade, 90 AS points;
INSERT INTO test_ranges VALUES ('class 1', 'B', 75),('class 2', 'A', 80);
CREATE TABLE test_results AS SELECT 'class 1' AS category, 100 AS points;
INSERT INTO test_results VALUES ('class 1', 95),('class 1', 94),('class 1', 85),('class 1', 55),('class 1', 44),('class 1', 33);
还有表的内容:
SELECT * FROM test_ranges;
+----------+-------+--------+
| category | grade | points |
+----------+-------+--------+
| class 1 | A | 90 |
| class 1 | B | 75 |
| class 2 | A | 80 |
+----------+-------+--------+
结果:
SELECT * FROM test_results;
+----------+--------+
| category | points |
+----------+--------+
| class 1 | 100 |
| class 1 | 95 |
| class 1 | 94 |
| class 1 | 85 |
| class 1 | 55 |
| class 1 | 44 |
| class 1 | 33 |
+----------+--------+
我希望每个年级的每个类别都有多个条目。
当我尝试使用LEFT JOIN进行选择时,它的工作方式几乎与我想的一样,但计数不正确。
SELECT test_ranges.category,grade,count(*) FROM test_ranges
LEFT JOIN test_results USING(category)
GROUP BY category,grade;
+----------+-------+----------+
| category | grade | count(*) |
+----------+-------+----------+
| class 1 | A | 7 |
| class 1 | B | 7 |
| class 2 | A | 1 |
+----------+-------+----------+
当我添加WHERE
子句时,我有正确的计数值,但不是每个category
和grade
:
SELECT test_ranges.category,grade,COUNT(*) FROM test_ranges
LEFT JOIN test_results USING(category)
WHERE test_results.points>=test_ranges.points
GROUP BY category,grade;
+----------+-------+----------+
| category | grade | count(*) |
+----------+-------+----------+
| class 1 | A | 3 |
| class 1 | B | 4 |
+----------+-------+----------+
我希望得到类似的结果:
+----------+-------+----------+
| category | grade | count(*) |
+----------+-------+----------+
| class 1 | A | 3 |
| class 1 | B | 4 |
| class 2 | A | 0 |
+----------+-------+----------+
修改
我发现:
SELECT test_ranges.category,grade,COUNT(test_results.points) FROM test_ranges
LEFT JOIN test_results USING(category)
WHERE test_results.points>=test_ranges.points OR test_results.points IS NULL
GROUP BY category,grade;
返回正确的东西。这里的问题只是表现。在我原来的问题中,test_ranges是(查询连接查询)语句,结果给出了大约32行,test_results有300k行。
答案 0 :(得分:3)
使用on
子句:
select rg.category, rg.grade, ifnull(count(rs.points),0) as num
from test_ranges rg
left join test_results rs
on rg.category = rs.category
and rs.points >= rg.points
group by rg.category, rg.grade;
小提琴: http://sqlfiddle.com/#!9/d503a/4/0
正如戈登所说,你的预期结果有点奇怪。这表明每个得分A的人也会因为达到该阈值而对B进行评分。我不确定这是不是你真正想要的。我想你可以把它描绘成"至少得分为X等级的人数......"并且在这方面可能有用。无论如何,请注意。
答案 1 :(得分:1)
从test_ranges
开始并使用相关子查询:
select tr.category, tr.grade,
(select count(*)
from test_results tr2
where tr2.category = tr.category and
tr2.points >= tr.points
) as cnt
from test_ranges tr;
这实际上应该返回查询返回的内容。