在同一个表上使用连接错误

时间:2018-01-04 08:37:28

标签: mysql sql

我在从包含不同类型记录的表格中获取正确数据时遇到问题,而且我想计算每个记录中有多少记录。

这是一个更简单的架构:

companies:

| id | name     |
|----|----------|
| 1  | company1 |
| 2  | company2 |



messages:

| id | type    | text  | companies_id |
|----|---------|-------|--------------|
| 1  | request | blah  | 1            |
| 2  | report  | blah! | 1            |
| 3  | request | foo   | 2            |
| 4  | request | bar   | 2            |
| 5  | report  | hi!   | 2            |

指向SQL Fiddle的链接:

http://sqlfiddle.com/#!9/e7237f/6

请注意,如果我只使用一个联接,为了获得任何公司的一种消息类型的总和,它可以工作:

SELECT c.*, COUNT(m1.id) as requests
FROM companies c 
LEFT JOIN messages m1 ON m1.companies_id = c.id AND m1.type = 'request' 
GROUP BY c.id;

如果我尝试列出任何公司所有消息类型的总数,我就不会这样做,例如我在这里做的事情:

SELECT c.*, COUNT(m1.id) as requests, COUNT(m2.id) as reports
FROM companies c 
LEFT JOIN messages m1 ON m1.companies_id = c.id AND m1.type = 'request' 
LEFT JOIN messages m2 ON m2.companies_id = c.id AND m2.type = 'report' 
GROUP BY c.id;

我做错了什么?我认为必须有一种方法来使用连接而不是嵌套查询,我想这会慢得多。

4 个答案:

答案 0 :(得分:4)

case只有一次。使用SELECT c.*, SUM(case when m1.type = 'request' then 1 else 0 end) as requests, SUM(case when m1.type = 'report' then 1 else 0 end) as reports FROM companies c LEFT JOIN messages m1 ON m1.companies_id = c.id GROUP BY c.id; 表达式进行条件计数

SELECT c.*,
SUM(m.type = 'request') as requests,
SUM(m.type = 'report')  as reports
FROM companies c 
LEFT JOIN messages m ON m.companies_id = c.id
GROUP BY c.id;

答案 1 :(得分:2)

我认为,不需要两个不同的连接;

SELECT 
c.id, 
sum(case when m1.type = 'request' then 1 else 0 end) as requests,
sum(case when m1.type = 'report' then 1 else 0 end) as reports
FROM companies c 
LEFT JOIN messages m1 ON m1.companies_id = c.id
GROUP BY c.id;

答案 2 :(得分:1)

最简单的解决方案是计算不同的ID:

SELECT c.*, COUNT(DISTINCT m1.id) as requests, COUNT(DISTINCT m2.id) as reports
FROM companies c 
LEFT JOIN messages m1 ON m1.companies_id = c.id AND m1.type = 'request' 
LEFT JOIN messages m2 ON m2.companies_id = c.id AND m2.type = 'report' 
GROUP BY c.id;

答案 3 :(得分:1)

您可以使用单个连接子句

来简化查询,以便根据您的类型获得不同的计数
sum

在Mysql中如果使用{{1}}条件表达式,它将根据是否满足条件返回布尔值0/1

DEMO