查找跨多个表的记录的最小和最大日期

时间:2012-07-10 03:31:56

标签: mysql date ifnull

我有3张桌子:

file_list => list of all files on web server  
stats_web => number of pageviews from public web  
stats_reg => number of pageviews from "registered users" 

我在http://sqlfiddle.com/#!2/98c6a/1/0

上有架构和一些示例数据

我正在尝试计算公众或注册用户首次点击文件的日期。

当前SQL如下所示:

SELECT
    list.path,
    list.mod_date,
    IF(MIN(ifnull(web.hit_date, 0000-00-00)) < MIN(ifnull(reg.hit_date, 0000-00-00)), MIN(ifnull(web.hit_date, 0000-00-00)), MIN(ifnull(reg.hit_date, 0000-00-00))) AS 'min_date',
    IF(MAX(ifnull(web.hit_date, 0000-00-00)) > MAX(ifnull(reg.hit_date, 0000-00-00)), MAX(ifnull(web.hit_date, 0000-00-00)), MAX(ifnull(reg.hit_date, 0000-00-00))) AS 'max_date',    
    SUM(ifnull(web.pages, 0)) + SUM(ifnull(reg.pages, 0)) AS 'page_views'
FROM
    file_list list
    LEFT JOIN
         stats_web web ON list.path = web.path
    LEFT JOIN
         stats_reg reg ON list.path = reg.path
WHERE
list.path LIKE '/web/htdocs/%'
GROUP BY list.path;

问题是如果记录只出现在其中一个统计表中,则最小日期始终为0。 这是因为MIN和MAX上的ifnull()但是如果我不使用ifnull()那么min和max日期都返回NULL。

1 个答案:

答案 0 :(得分:1)

当使用ifnull的第二个参数来比较最小值时,你应该使用遥远未来的日期。否则,第一个null会使0000-00-00成为最小值,并且因为它是最早可能的日期,所以没有其他日期可以将其击败成为最小值。

如果您将查询的第四行更改为

IF(MIN(ifnull(web.hit_date, 9999-12-31)) < MIN(ifnull(reg.hit_date, 9999-12-31)), MIN(ifnull(web.hit_date, 9999-12-31)), MIN(ifnull(reg.hit_date, 9999-12-31))) AS 'min_date'

你应该得到正确的结果。