[英]how to group by with a sql subqueries
I can't think clearly at the moment, I want to return counts by station_id, an example of output would be:我现在想不清楚,我想通过 station_id 返回计数,output 的一个例子是:
station 1 has 3 fb post, 6 linkedin posts, 5 email posts station 2 has 3 fb post, 6 linkedin posts, 5 email posts第 1 站有 3 个 fb 帖子,6 个linkedin 帖子,5 个 email 帖子 第 2 站有 3 个 fb 帖子,6 个linkedin 帖子,5 个 email 帖子
So I need to group by the station id, my table structure is所以我需要按站号分组,我的表结构是
CREATE TABLE IF NOT EXISTS `posts` (
`post_id` bigint(11) NOT NULL auto_increment,
`station_id` varchar(25) NOT NULL,
`user_id` varchar(25) NOT NULL,
`dated` datetime NOT NULL,
`type` enum('fb','linkedin','email') NOT NULL,
PRIMARY KEY (`post_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=x ;
The query I have so far is returning station 0 as having 2 linkedin posts when it has one (2 in the db tho)到目前为止,我的查询是返回站 0,因为它有一个(数据库中的 2 个)有 2 个linkedin 帖子
SELECT Station_id, (select count(*) FROM posts WHERE type = 'linkedin') AS linkedin_count, (select count(*) FROM posts WHERE type = 'fb') AS fb_count, (select count(*) FROM posts WHERE type = 'email') AS email_count FROM `posts` GROUP BY station_id;
Or, the fastest way, avoiding joins and subselects to get it in the exact format you want:或者,最快的方法是避免连接和子选择以获取您想要的确切格式:
SELECT
station_id,
SUM(CASE WHEN type = 'linkedin' THEN 1 ELSE 0 END) AS 'linkedin',
SUM(CASE WHEN type = 'fb' THEN 1 ELSE 0 END) AS 'fb',
SUM(CASE WHEN type = 'email' THEN 1 ELSE 0 END) AS 'email'
FROM posts
GROUP BY station_id;
Outputs:输出:
+------------+----------+------+-------+
| station_id | linkedin | fb | email |
+------------+----------+------+-------+
| 1 | 3 | 2 | 5 |
| 2 | 2 | 0 | 1 |
+------------+----------+------+-------+
You may also want to put an index on there to speed it up您可能还想在其中放置一个索引以加快速度
ALTER TABLE posts ADD INDEX (station_id, type);
Explain output:解释output:
+----+-------------+-------+-------+---------------+------------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------------+---------+------+------+-------------+
| 1 | SIMPLE | posts | index | NULL | station_id | 28 | NULL | 13 | Using index |
+----+-------------+-------+-------+---------------+------------+---------+------+------+-------------+
As implied by gnif's answer, having three correlated sub_queries has a performance over-head.正如 gnif 的回答所暗示的那样,拥有三个相关的 sub_queries 会产生性能开销。 Depending on the DBMS you're using, it could perform similarly to having a self join three times.
根据您使用的 DBMS,它的执行类似于 3 次自联接。
gnif's methodology ensures that the table is only parsed once, without the need for joins, correlated sub_queries, etc. gnif 的方法确保表只解析一次,而不需要连接、相关子查询等。
The immediately obvious down-side of gnif's answer is that you don't ever get records for 0's. gnif 的答案最明显的缺点是你永远不会得到 0 的记录。 If there are no fb types, you just don't get a record.
如果没有 fb 类型,您就不会获得记录。 If that is not an issue, I'd go with his answer.
如果这不是问题,我会 go 回答他。 If it is an issue, however, here is a version with similar methodology to gnif, but matching your output format...
但是,如果这是一个问题,这里有一个与 gnif 方法相似的版本,但与您的 output 格式匹配...
SELECT
station_id,
SUM(CASE WHEN type = 'linkedin' THEN 1 ELSE 0 END) AS linkedin_count,
SUM(CASE WHEN type = 'fb' THEN 1 ELSE 0 END) AS fb_count,
SUM(CASE WHEN type = 'email' THEN 1 ELSE 0 END) AS email_count
FROM
posts
GROUP BY
station_id
Give this a go:给这个 go:
SELECT station_id, type, count(*) FROM posts GROUP BY station_id, type
The output format will be a little different to what your attempting to get, but it should provide the statistics your trying to retrieve. output 格式与您尝试获取的格式略有不同,但它应该提供您尝试检索的统计信息。 Also since its a single query it is much faster.
此外,由于它是一个单一的查询,它要快得多。
-- Edit, added example result set -- 编辑,添加示例结果集
+------------+----------+----------+
| station_id | type | count(*) |
+------------+----------+----------+
| 1 | fb | 2 |
| 1 | linkedin | 3 |
| 1 | email | 5 |
| 2 | linkedin | 2 |
| 2 | email | 1 |
+------------+----------+----------+
try this:尝试这个:
SELECT p.Station_id,
(select count(*) FROM posts WHERE type = 'linkedin' and station_id=p.station_id) AS linkedin_count,
(select count(*) FROM posts WHERE type = 'fb' and station_id=p.station_id) AS fb_count,
(select count(*) FROM posts WHERE type = 'email' and station_id=p.station_id) AS email_count
FROM `posts` p GROUP BY station_id
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.