从指定范围内的表中获取条目数

时间:2015-03-10 23:17:52

标签: mysql sql

我正在尝试使用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子句时,我有正确的计数值,但不是每个categorygrade

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行。

2 个答案:

答案 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;

这实际上应该返回查询返回的内容。