MySQL选择日期范围内的所有日期,即使当天没有数据可用

时间:2015-05-06 10:32:57

标签: php mysql date

我每天都有条目作为打卡/打卡时钟。我想显示日期和周日的所有日期,并显示日期,即使当天没有找到数据。

示例:

Monday 2015-05-04
- 2015-05-04 10:30:00
- 2015-05-04 15:45:34

Tuesday 2015-05-05
- 2015-05-05 08:43:23
- 2015-05-05 17:18:13

Wednesday 2015-05-06
- 2015-05-06 09:03:12

Thursday 2015-05-07
0 Entries

Friday 2015-05-08
0 Entries

数据库架构如下所示:

id | user_id | punch_time | punch_status

我希望能够将给予MySQL的日期更改为任何时间戳,并显示该周的日期和结果。

谢谢:D

任何想法为什么这不起作用以获得没有记录的日子?

SELECT * FROM punch_clock, calendar_table WHERE calendar_table.dt = DATE(punch_clock.punch_time) && calendar_table.week_num = $week && calendar_table.y = $year ORDER BY punch_clock.punch_time

较新的查询

 SELECT * FROM punch_clock LEFT JOIN calendar_table ON calendar_table.dt = DATE(punch_clock.punch_time) WHERE calendar_table.week_num = 18 && calendar_table.y = 2015;

3 个答案:

答案 0 :(得分:2)

对于MySQL,我通常会为此目的使用日历表(例如包含所有日期,直到2030年) 它允许做许多其他事情,比如这种查询,管理特殊日子等。

你想要LEFT JOIN你的桌子,我的意思是这个日历表必须“左侧定位”

上次查询,我会这样做:

SELECT *
FROM calendar AS cal
LEFT JOIN punch_clock AS puc
  ON (cal.dt = DATE(puc.punch_time))
WHERE TRUE
  AND cal.week_num = 18
  AND cal.y = 2015
;

没试过,但这就是主意。

答案 1 :(得分:0)

试试这个:

SELECT *
FROM
  (
    SELECT a.Date AS mydate
    FROM (
           SELECT date('2015-05-08') - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY AS Date
           FROM (SELECT 0 AS a
                 UNION ALL SELECT 1
                 UNION ALL SELECT 2
                 UNION ALL SELECT 3
                 UNION ALL SELECT 4
                 UNION ALL SELECT 5
                 UNION ALL SELECT 6
                 UNION ALL SELECT 7
                 UNION ALL SELECT 8
                 UNION ALL SELECT 9) AS a
             CROSS JOIN (SELECT 0 AS a
                         UNION ALL SELECT 1
                         UNION ALL SELECT 2
                         UNION ALL SELECT 3
                         UNION ALL SELECT 4
                         UNION ALL SELECT 5
                         UNION ALL SELECT 6
                         UNION ALL SELECT 7
                         UNION ALL SELECT 8
                         UNION ALL SELECT 9) AS b
             CROSS JOIN (SELECT 0 AS a
                         UNION ALL SELECT 1
                         UNION ALL SELECT 2
                         UNION ALL SELECT 3
                         UNION ALL SELECT 4
                         UNION ALL SELECT 5
                         UNION ALL SELECT 6
                         UNION ALL SELECT 7
                         UNION ALL SELECT 8
                         UNION ALL SELECT 9) AS c
         ) a
    WHERE a.Date BETWEEN '2015-05-04' AND '2015-05-08'
  ) dates
  LEFT JOIN
  (
    SELECT *
    FROM
      table1
  ) data
    ON DATE_FORMAT(dates.mydate, '%Y%m%d') = DATE_FORMAT(data.punch_time, '%Y%m%d')

SQL小提琴:http://sqlfiddle.com/#!9/72ee3/15/0

对于您的问题,这是一个快速但不理想的解决方案。但我认为它已经足够使用了。

如果您想解决问题"完美",建议您阅读本文:http://www.brianshowalter.com/calendar_tables

答案 2 :(得分:0)

即使这是一个非常古老的问题,我也不喜欢额外的日历表的想法,并提出了这个问题,并根据问题进行了调整。

SELECT pc.`id`, pc.`user_id`, pc.`punch_status`, dates.`date` FROM punch_clock pc RIGHT JOIN (SELECT week.`date` FROM (
    SELECT CURDATE() AS `date`
       UNION SELECT CURDATE() + INTERVAL 1 DAY
       UNION SELECT CURDATE() + INTERVAL 2 DAY
       UNION SELECT CURDATE() + INTERVAL 3 DAY
       UNION SELECT CURDATE() + INTERVAL 4 DAY
       UNION SELECT CURDATE() + INTERVAL 5 DAY
       UNION SELECT CURDATE() + INTERVAL 6 DAY
       UNION SELECT CURDATE() - INTERVAL 1 DAY
       UNION SELECT CURDATE() - INTERVAL 2 DAY
       UNION SELECT CURDATE() - INTERVAL 3 DAY
       UNION SELECT CURDATE() - INTERVAL 4 DAY
       UNION SELECT CURDATE() - INTERVAL 5 DAY
       UNION SELECT CURDATE() - INTERVAL 6 DAY
    ) AS week 
WHERE YEARWEEK(`date`, 0) = YEARWEEK(CURDATE(), 0)) AS dates ON dates.`date` = DATE(pc.`punch_time`) ORDER BY dates.`date`

不完全漂亮,但它可以在没有额外表格的情况下完成工作。这使用周一至周日的一周,周日至周一周使用YEARWEEK(xxx, 1)