MySQL:计算多个状态的持续时间

时间:2012-10-03 13:57:41

标签: mysql sql left-join aggregate datediff

我有一个包含俱乐部会员信息的数据库。每个成员在任何时候都可以是三种不同的状态之一(活跃的,退伍的,关联的)。我将它分解为三个表格。成员表,包含所有成员信息,状态表包含status_name和status_id,以及一个包含member_id,status_id,date_from和date_to的网格表。

我正在尝试计算会员在每个状态下花费的时间。我目前通过以下查询计算会员在“活动”状态下花费的总时间:

SELECT first_name, last_name, 
 (DATE_FORMAT( FROM_DAYS( SUM( DATEDIFF( IFNULL( q.date_to, NOW() ) , q.date_from ) ) ) , "%Y" ) +0) as service_years 
 FROM member a
 LEFT JOIN member_status q on a.id = q.member_id AND q.status_id = 1
 GROUP BY a.id

我知道我可以通过在左连接中省略AND来拉出此人成为会员的总时间,但是我无法找到计算单个查询中每个状态的时间的方法。

我理想的结果将是:

 -----------------------------------------------------------
 |member_name | active_years | veteran_years | total_years |
 -----------------------------------------------------------
 |name        | 5            | 5             | 10          |
 -----------------------------------------------------------

有没有办法在单个查询中完成我正在寻找的内容?

2 个答案:

答案 0 :(得分:0)

您应该可以执行以下操作:使用CASE语句确定状态名称,然后根据状态计算总年数:

SELECT first_name, 
  last_name, 
  CASE WHEN status_name = 'active' 
    then (DATE_FORMAT( FROM_DAYS( SUM( DATEDIFF( IFNULL( q.date_to, NOW() ) , q.date_from ) ) ) , "%Y" ) +0) end as active_years,
  CASE WHEN status_name = 'veteran' 
    then (DATE_FORMAT( FROM_DAYS( SUM( DATEDIFF( IFNULL( q.date_to, NOW() ) , q.date_from ) ) ) , "%Y" ) +0) end as active_years,
  (DATE_FORMAT( FROM_DAYS( SUM( DATEDIFF( IFNULL( q.date_to, NOW() ) , q.date_from ) ) ) , "%Y" ) +0) as total_years,
FROM member a
LEFT JOIN member_status q 
  on a.id = q.member_id 
  AND q.status_id = 1
GROUP BY a.id, a.first_name, a.last_name

如果您发布一些示例数据,将更容易确定正确的查询

答案 1 :(得分:0)

假设1 =有效且2 =退伍军人,这样的事情应该有效:

SELECT first_name, last_name, 
 (DATE_FORMAT( FROM_DAYS( SUM( case when q.status_id = 1 then DATEDIFF( IFNULL( q.date_to, NOW() ) , q.date_from ) ) else 0 end ) , "%Y" ) +0) as active_years,
 (DATE_FORMAT( FROM_DAYS( SUM( case when q.status_id = 2 then DATEDIFF( IFNULL( q.date_to, NOW() ) , q.date_from ) ) else 0 end ) , "%Y" ) +0) as veteran_years,
(DATE_FORMAT( FROM_DAYS( SUM( DATEDIFF( IFNULL( q.date_to, NOW() ) , q.date_from ) ) ) , "%Y" ) +0) as total_years 
 FROM member a
  LEFT JOIN member_status q on a.id = q.member_id AND q.status_id in (1,2)
 GROUP BY a.id

另一种选择是多次加入member_status表。