查询不会返回我认为的所有行

时间:2011-12-09 17:36:27

标签: mysql sql

我有这个查询

SELECT category_name, categories.category_id, problems.problem_id, COUNT(problems.problem_id) as num_problems
FROM categories 
JOIN problem_categories 
ON problem_categories.category_id = categories.category_id
JOIN problems 
ON problems.problem_id = problem_categories.category_id
WHERE is_top = 1
GROUP BY category_name, categories.category_id, problems.problem_id;

返回2行。但是大约有9个项与is_top = 1子句相匹配。我不确定他们为什么不归还?

以下是目前返回的内容:

+---------------+------------+--------------+
| category_name | problem_id | num_problems |
+---------------+------------+--------------+
| Entertainment |         46 |            1 |
| Home          |         49 |            2 |
+---------------+------------+--------------+
2 rows in set (0.00 sec)

以下是我的表格:

mysql> describe categories;
+----------------------+---------------+------+-----+---------+----------------+
| Field                | Type          | Null | Key | Default | Extra          |
+----------------------+---------------+------+-----+---------+----------------+
| category_id          | int(10)       | NO   | PRI | NULL    | auto_increment |
| creator_id           | int(10)       | NO   |     | NULL    |                |
| category_name        | varchar(100)  | NO   | UNI | NULL    |                |
| category_description | varchar(5000) | YES  |     | NULL    |                |
| category_date        | date          | NO   |     | NULL    |                |
| is_top               | tinyint(1)    | YES  |     | NULL    |                |
| problem_count        | int(8)        | YES  |     | NULL    |                |
+----------------------+---------------+------+-----+---------+----------------+
7 rows in set (0.01 sec)

mysql> describe problem_categories;
+---------------------+---------+------+-----+---------+----------------+
| Field               | Type    | Null | Key | Default | Extra          |
+---------------------+---------+------+-----+---------+----------------+
| problem_category_id | int(10) | NO   | PRI | NULL    | auto_increment |
| problem_id          | int(10) | NO   | MUL | NULL    |                |
| creator_id          | int(10) | NO   |     | NULL    |                |
| category_id         | int(10) | NO   |     | NULL    |                |
| category_date       | date    | NO   |     | NULL    |                |
+---------------------+---------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

mysql> describe problems;
+---------------------+---------------+------+-----+---------+----------------+
| Field               | Type          | Null | Key | Default | Extra          |
+---------------------+---------------+------+-----+---------+----------------+
| problem_id          | int(10)       | NO   | PRI | NULL    | auto_increment |
| creator_member_id   | int(10)       | NO   |     | NULL    |                |
| problem_title       | varchar(100)  | NO   |     | NULL    |                |
| problem_description | varchar(3000) | YES  |     | NULL    |                |
| problem_date        | date          | NO   |     | NULL    |                |
| upvotes             | int(7)        | YES  |     | NULL    |                |
| downvotes           | int(7)        | YES  |     | NULL    |                |
| date_updated        | date          | YES  |     | NULL    |                |
+---------------------+---------------+------+-----+---------+----------------+
8 rows in set (0.00 sec)

为什么其他顶级类别没有得到他们的计数的任何想法?

谢谢!

顺便说一句,返回的2个类别的计数是正确的。

3 个答案:

答案 0 :(得分:3)

加入条件problems.problem_id = problem_categories.category_id看起来不正确。

这应该是problems.problem_id = problem_categories.problem_id

您可能还需要考虑LEFT JOIN带回没有问题的类别计数。

答案 1 :(得分:1)

没有看到你的数据很难说,但我建议将内部连接更改为左连接

e.g。

SELECT category_name, categories.category_id, problems.problem_id, COUNT(problems.problem_id) as num_problems
FROM categories 
LEFT JOIN problem_categories 
ON problem_categories.category_id = categories.category_id
LEFT JOIN problems 
ON problems.problem_id = problem_categories.category_id
WHERE is_top = 1
GROUP BY category_name, categories.category_id, problems.problem_id;

由于您遇到特定问题ID的问题,我通常会编写一个SQL语句,通过执行类似

的操作来帮助调试
SELECT is_top , category_name, categories.category_id, problems.problem_id
FROM 
       problems
       LEFT JOIN problem_categories 
        ON problems.problem_id = problem_categories.category_id
       LEFT JOIN categories 
      ON problem_categories.category_id = categories.category_id

WHERE  problems.problem_id = 1234 --Whatever the ID is that you think should be showing up

这将有助于确定is_top是否真实,以及识别我对JOINS所做的任何假设(例如连接字段中的空值)

答案 2 :(得分:1)

因为您正在与其他2个表进行两次内部联接,这些表可能没有相应的行。