返回一段时间内每天创建,关闭和打开的记录数

时间:2012-09-07 14:03:00

标签: php mysql

我有一个存储创建和关闭日期的表。我尝试做的是运行一个查询,在给定的时间段内,每天,创建的记录数量,关闭的数量以及打开的数量。表结构:

+------------------------+
| Field      | Structure |
+------------+-----------+
| id         | int       |
| start_date | datetime  |
| close_date | datetime  |
+------------+-----------+

前两个查询不是问题 - 我现在正在使用的是:

SELECT COUNT(*), start_date FROM dates 
WHERE start_date BETWEEN 'start' AND 'end' 
GROUP BY start_date 
ORDER BY start_date ASC

SELECT COUNT(*), close_date FROM dates 
WHERE close_date BETWEEN 'start' AND 'end' 
GROUP BY close_date 
ORDER BY close_date ASC

第三个问题是一个问题 - 我可以告诉我有多少是在桌子上那天存在的那天开放的,但我还没想到的是如何让它写出来一年中的每一天排,并给我那天的计数。

这是第一个问题。

第二个是我想让它给我一个这样的结果,我无法弄清楚如何去做 - 在这里搜索给了我一些错误的开始,但没有什么可靠的。< / p>

+------------+--------+--------+--------+
|    Date    | Opened | Closed | Active |
+------------+--------+--------+--------+
| 2012-05-06 | 3      | 2      | 7      |
| 2012-05-07 | 2      | 0      | 9      |
| 2012-05-08 | 0      | 0      | 9      |
| 2012-05-09 | 0      | 3      | 6      |
+------------+--------+--------+--------+

我完全愿意在必要时运行单独的查询,并且如果必须的话,用代码而不是数据库处理所有查询 - 我非常确定我可以编写来自单个查询的所有查询数据到一个数组,然后循环来构建报告,但我真的不喜欢。有什么建议吗?

3 个答案:

答案 0 :(得分:0)

  

我可以告诉我有多少人在桌子上那天有一天开放,但我没想到的是如何让它在一年中的每一天都写出来并给出我当天的数量。

我理解为:您想要计算每个关闭日期的问题?     

SELECT COUNT(*) FROM dates WHERE your_condition GROUP BY DAY_OF_YEAR(close_date)

答案 1 :(得分:0)

仅使用SQL语句创建这样的聚合表非常困难。您将需要使用子查询,UNION语句和/或可能的存储过程来获取逻辑点,以便在您呈现时显示该表。

您已经进行的两个查询比我上面提到的方法快得多。 PHP数组肯定会帮助您获得所需。

所以:

第1步

SELECT COUNT(*) AS active_before_start 
WHERE start_date < 'start'
AND close_date IS NULL

获取该号码并将其存储在$ active_before_start。

第2步

SELECT COUNT(*) AS total_opened, start_date FROM dates 
WHERE start_date BETWEEN 'start' AND 'end' 
GROUP BY start_date 
ORDER BY start_date ASC

将这些结果放入数组

foreach ($results as $result)
{
    $key = $result->start_date;
    $final_table[$key]['date']   = $key;
    $final_table[$key]['opened'] = $result->total_opened;
}

第3步

SELECT COUNT(*) AS total_closed, close_date FROM dates 
WHERE close_date BETWEEN 'start' AND 'end' 
GROUP BY close_date 
ORDER BY close_date ASC

再次存储数组中的那些

foreach ($results as $result)
{
    $key = $result->close_date;
    $final_table[$key]['date']   = $key;
    $final_table[$key]['closed'] = $result->total_closed;
}

第4步

现在你可以遍历表来操纵数据,以便它产生你需要的结果:

$results_table = array();
$active        = $active_before_start;
foreach ($final_table as $key => $item)
{
    $opened = (isset($item['opened']) ? $item['opened'] : 0;
    $closed = (isset($item['closed']) ? $item['closed'] : 0;
    $active = $active + ($opened' - $closed);

    $results_table[$key]['date']   = $key;
    $results_table[$key]['opened'] = $opened;
    $results_table[$key]['closed'] = $closed;
    $results_table[$key]['active'] = $active;
}

从那时起,您总是可以执行ksort以防万一,以显示已排序的数组结果。

HTH

答案 2 :(得分:0)

此查询很棘手,因为您需要每个日期的状态列表。

在此查询中,日期在连接查询中生成。 为此我假设它有

使用相同的表
  • 记录数&gt; =日期范围之间的日期数
  • id-s必须连续到日期范围之间的日期数

您可以将其替换为您自己的日期列表生成子查询。

set @start :='2012-05-06';
set @end :='2012-05-09';

select cdate as Date
     , sum(start_date = cdate) Opened
     , sum(close_date = cdate or close_date is null) Closed
     , sum(start_date <= cdate and (close_date>cdate or close_date is null)) Active
from dates
join (select date(@start + interval id-1 day) cdate from dates where id <= to_days(@end)-to_days(@start)+1) d
  on start_date <= cdate and (close_date>=cdate or close_date is null)
where start_date <= @end 
  and (close_date >= @start or close_date is null)
group by cdate
order by cdate
;