2011-03-19 41 views
3

如何使用不同的查询条件为一个表中的两列计数记录?一个查询中的Mysql多重计数

表的样子:

user_id | date  | status 
------------------------------ 
     1  | 2011-01-02 | 1 
     2  | 2011-01-03 | 1 
     3  | 2011-01-02 | 0 
     4  | 2011-01-03 | 1 
     1  | 2011-01-02 | 1 

我想在一个查询计数两个值。第一个是按状态分的user_id组的数量,第二个是按日期分组的user_id组的数量。

我该怎么做?

+0

使用像SELECT COUNT ... – 2011-03-19 17:01:28

+0

请提供您的预期输出的一个例子,因为每个状态的计数与每个日期的计数没有关系。笛卡尔产品是唯一的结果。 – 2011-03-19 17:16:52

回答

4

在同一查询中不能有不同的GROUP BY子句 - 每个计数必须位于独立查询中。

但是你可以使用子查询单查询/结果集返回输出(SELECT子句中的子查询):

SELECT COUNT(a.user_id) AS numUsersPerStatus, 
      (SELECT COUNT(b.user_id) 
      FROM YOUR_TABLE b 
     GROUP BY b.date) AS numUsersPerDate 
    FROM YOUR_TABLE a 
GROUP BY a.status 
+1

如果在Select Column中使用子查询,它应该只返回1行和1列,numUsersPerDate将为不同的日期返回多行?我认为这个查询可以给基于数据的运行时错误?请纠正我,如果我错了..... – 2011-03-19 17:11:37

+0

@Nitin Midha:不,这不会导致运行时错误。 numUsersPerDate将为每个状态计数重复 - 结果将是笛卡尔积。 – 2011-03-19 17:15:02

+1

然后我希望它应该在from子句中加入一个交叉....这是SQL Server和MySQL之间已知的区别吗?据我记得,在SQL Server中,它会给出错误... – 2011-03-19 17:18:06

0

不要

您应该使用两个查询。用单个查询来做这件事没有什么好处。

如果你真的做到这一点,你可以试试这个:

SELECT 'date' AS grptype, date AS grp, COUNT(DISTINCT user_id) AS cnt 
FROM yourtable 
GROUP BY date 
UNION ALL 
SELECT 'status' AS grptype, status AS grp, COUNT(DISTINCT user_id) AS cnt 
FROM yourtable 
GROUP BY status 

结果:

 
grptype grp   cnt 
date  2011-01-02 2 
date  2011-01-03 2 
status  0   1 
status  1   3 

不过,我想强烈反对这样做建议。你需要两个不同的和不相关的结果集,所以你应该使用两个单独的查询。

+0

UNION原样不起作用 - 日期和状态列是不同的数据类型。并且您希望将其用作派生表/内联视图,以最终使用MAX将其压缩为更少的行。 – 2011-03-19 17:04:53

+0

为什么你会建议不要这样做? – rahmanisback 2011-03-19 17:07:22

+1

@rahmanisback:因为它是SQL的滥用。每当您将数据类型混合在单个列中时,独角兽就会死亡。在大多数数据库中,甚至不允许这样的事情。 MySQL允许它由于类型转换。但仅仅因为你*可以*并不意味着你*应该*。 – 2011-03-19 17:09:38