MySQL - 从表中选择缺少的日期?

时间:2013-03-30 05:33:07

标签: mysql select

假设您有以下表格values

date       | value
2012-01-01 |    8
2012-01-02 |    3
2012-01-03 |   17
2012-01-09 |  100
2012-01-12 |    2

现在假设您要选择2012-01-02和2012-01-12之间的所有日期,并显示其值(如果存在)。如果您只是在表中查询适当的日期范围,那么由于显而易见的原因,将没有没有值的日期。有没有办法在查询中填写这些日期?

显而易见的解决方案是创建一个表dates,它只存储可能出现的所有日期的列表,然后从dates表中选择并加入values到它,但是如果可以的话,我想要一个不依赖于创建单列表的解决方案。

值得注意的是:existing上有questions SO关于此主题,但它们都来自2010年(至少是我在搜索时发现的那些),并且MySQL功能有在那个时代成长;现在可能有一个动态的解决方案。如果情况并非如此,并且dates表仍然是最佳解决方案,那么这个问题应该作为副本关闭。

1 个答案:

答案 0 :(得分:0)

其他人缺乏答案告诉我,目前,如果没有包含这些日期的表格,就无法遍历MySQL中的一系列日期。但是,我已经用PHP编写了一些代码,用于填写事实后的缺失日期:

function formatResults($inbound, $from, $to) {
    $results = array();
    $count = 0;

    // In order not to lose any results, we have to change how the results are referenced
    $indexes = array();
    $stats = array();
    foreach ($inbound as $stat) {
        // ['listindex'] is the date, renamed in the query
        $stats[$stat['listindex']] = $stat;
    }

    // In a function in case you want to pop it out
    function dateArray($from, $to) {
        $begin = new DateTime($from);
        $end = new DateTime($to);
        $interval = DateInterval::createFromDateString('1 day');
        $days = new DatePeriod($begin, $interval, $end);
        $baseArray = array();
        foreach ($days as $day) {
            $dateKey = $day->format("Y-m-d");
            $baseArray[] = $dateKey;
        }
        $baseArray[] = $to;
        return $baseArray;
    }
    $indexes = dateArray($from, $to);

    // Now all the rows we need to return are uniquely identified in $indexes
    // So we traverse $indexes to create our results array, rather than relying on $inbound
    foreach($indexes as $index) if ($index != '') {
        $data = array();
        // Make sure we do not run into any 'missing index' problems
        if (!isset($stats[$index]))
            $stats[$index] = array(
                'listindex' => $index,
                // ... populate full list of empty fields
            );
        foreach ($stats[$index] as $key => $value) {
            $data[] = $value;
        }
        $results[$count] = $data;
        $count++;
    }
    return $results;
}