【问题标题】:create calendar table and join it to my table - lost as can be创建日历表并将其加入我的表 - 可能会丢失
【发布时间】:2020-08-24 17:43:00
【问题描述】:

我不擅长 MYSQL,但我正在努力学习。我需要创建一个日历表并将其左连接到我的数据表中。原因是我每周都在计算预订,如果那一周没有预订,则需要显示“0”。我不能使用我不认为的标准日历表,因为我不想永远手动填写每周。我正在寻找一种解决方案,可以在没有人工监督的情况下将日期添加到未来。与我发现的一些示例不同,这应该是动态的并且永无止境。我使用的是 MYSQL 5.4

对于日历表,我拼凑了这个,但认为它不正确:

SELECT 
DATE(booking_date + INTERVAL (6 - WEEKDAY(booking_date)) DAY) EndOfWeekDate
FROM my_table
group by EndOfWeekDate
ORDER BY EndOfWeekDate DESC

并且我正在尝试将上述内容从左加入到:

SELECT DATE_FORMAT(booking_date, "%M %d %Y") AS week_Ending, CONCAT(YEAR(booking_date), '/', WEEK(booking_date)) AS week_name,
DATE(booking_date + INTERVAL (6 - WEEKDAY(booking_date)) DAY) EndOfWeekDate,
YEAR(booking_date), WEEK(booking_date), COUNT(*)
FROM my_table
GROUP BY EndOfWeekDate
ORDER BY EndOfWeekDate DESC

在玩了大约 2 个小时后,我还远远没有得到这个。是否有比我更有经验的人能够阐明我应该去哪里才能实现这一目标?

所需的显示:

2020 年 6 月 30 日 | 2020/26 | 2020 | 26 | 5
2020 年 7 月 6 日 | 2020/27 | 2020 | 27 | 0
2020 年 7 月 13 日 | 2020/28 | 2020 | 28 | 0
2020 年 7 月 20 日 | 2020/29 | 2020 | 29 | 2

样本数据
身份证 |日期 |姓名
12 | 2020-08-24 |鲍勃·史密斯

【问题讨论】:

  • 欢迎使用 stackoverflow。看起来您只是从一张表 (my_table) 中进行选择,因此对于您要完成的工作并不清楚。为了使用LEFT JOIN,您必须有 2 个可供选择的表。请提供表中数据的示例以及您希望结果集的外观示例。
  • 感谢现在编辑

标签: mysql date datetime


【解决方案1】:

@Ted 基本上你要做的是创建一个派生表,你可以LEFT JOIN你现有的表,这样一个月中的每一天都会被列出,你可以显示表中存在的日期的数据.此查询已准备好复制/粘贴,您只需将对 my_table 的引用更改为您要从中获取数据的表名。

这是示例查询:

SELECT `dateList`.`Date` AS `Date`,
    CONCAT(YEAR(`dateList`.`Date`),'/',DAY(`dateList`.`Date`)) AS `year_month`,
    YEAR(`dateList`.`Date`) AS `year`,
    DAY(`dateList`.`Date`) AS `day`,
    'Bob Smith' AS `name`, 
    CASE WHEN `mt`.`date` IS NULL THEN 0
    ELSE COUNT(`mt`.`id`) 
    END AS `amt`
FROM

-- ---------------------------------------------------------------------------------------------------------------------------
-- this is the part you can copy/paste to be used to left join in a table of your choice ----------------------------------
(
    SELECT `a`.`Date`
    FROM (
        SELECT LAST_DAY('2020-08-01') - 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`
    ) AS `a` 
    WHERE `a`.`Date` BETWEEN '2020-08-01' AND LAST_DAY('2020-08-01')
) AS `dateList` 
-- ---------------------------------------------------------------------------------------------------------------------------

LEFT JOIN `my_table` AS `mt` ON `dateList`.`Date` = DATE(`mt`.`date`)
    AND `mt`.`name` = 'Bob Smith'
GROUP BY `dateList`.`Date`
ORDER BY `dateList`.`Date` ASC

Here is a working example in sql fiddle.

如果这没有意义或者您需要不同的东西,请告诉我。

【讨论】:

  • 非常感谢您抽出宝贵的时间来写这一切。这看起来是一项艰巨的任务,我非常感谢您花时间做这件事。我查看了小提琴并在 MyPHPAdmin 中实现了它以获得相同的数据。我的问题是 - 我如何让这比 8 月份更进一步?
  • @Ted 您需要做的就是将BETWEEN 语句中这一行的开始日期:WHERE a.Date BETWEEN '2020-08-01' AND LAST_DAY('2020-08-01') 更改为您想去的月份的第一天。例如,假设您想从 2020 年 7 月到 2020 年 8 月进行查询,则该行将是:WHERE a.Date BETWEEN '2020-07-01' AND LAST_DAY('2020-08-01')
  • 知道了。我试图改变最后一天,认为那是“第一天”。只要有预订,这将继续填充到未来?我尝试将预订更改为 9/23 并重新运行查询,但表格仍然只显示 9/6。
  • @Ted 如果您将LAST_DAY 的两个位置的值更改为LAST_DAY('2020-09-01'),它应该会显示未来的日期。如果您希望它基于当前日期是动态的,您可以将LAST_DAY 的位置更改为LAST_DAY(NOW())。如果它仍然只给你 09/06/2020 并且它应该通过 09/23/2020 因为你更改了数据,请尝试在 sql fiddle 中重新创建它,这样我才能真正看到它正在发生,我可以提供帮助你进一步排除故障
  • 非常感谢。我现在将使用 NOW() 并看看几周后会发生什么,以确保它在我们进行时广告。再次感谢您花费额外的时间,并认为您投入到教我这方面。通过您的示例,我学到了很多东西以及将来如何做到这一点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-29
  • 1970-01-01
  • 2012-12-29
  • 1970-01-01
  • 1970-01-01
  • 2011-07-19
  • 1970-01-01
相关资源
最近更新 更多