【问题标题】:MySQL select all days in date range even if no data is available for dayMySQL 选择日期范围内的所有日期,即使当天没有可用数据
【发布时间】:2015-05-06 10:32:57
【问题描述】:

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

例子:

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;

【问题讨论】:

  • 什么是表结构?你试过什么?
  • 尝试抓取所需范围内的所有数据并按日期排序。然后用 php 循环遍历它
  • 你试过什么查询?
  • 您需要一个日历表来加入,以获取所有日期的值

标签: php mysql date


【解决方案1】:

对于 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
;

没试过,但就是这个主意。

【讨论】:

    【解决方案2】:

    试试这个:

    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

    【讨论】:

    • 感谢您的帮助。我已阅读文章并实现了日历表。我的下一步是在加入日期的 mysql 查询中同时包含 punch_clock 和 calendar_table 吗?
    • @tutchmedia 应该是这样。您可以将我的 SQL 中的 dates 替换为您的日历。
    • 除了不显示没有数据的日子外,效果很棒吗? (请参阅我在原始帖子中的查询)有什么想法吗?
    • 需要从你的日历表左连接到你的穿孔卡片表
    • 我似乎无法正确理解这一点。它仍然没有显示没有条目的日子(请参阅更新的查询) - 有什么想法吗?
    【解决方案3】:

    尽管这是一个非常老的问题,但我不喜欢额外日历表的想法,并提出了这个查询,并针对问题进行了调整。

    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)

    【讨论】:

      猜你喜欢
      • 2010-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-25
      • 2020-04-01
      相关资源
      最近更新 更多