我正在使用自定义PHP函数为单月生成可视日历,该日历根据包含开始日期和持续时间的表来阻止日期 - 例如:
...这是由数据产生的,表示该表应该从第14天开始4天,从第27天开始7天。
查询看起来像这样:
SELECT GROUP_CONCAT(DATE_FORMAT(start_date,'%d'),':', event_duration) AS info
FROM events
WHERE YEAR(start_date = '2012'
AND MONTH(start_date) = '07'
ORDER BY start_date
(您可以放心地忽略组concat并将数据作为单独的行返回,这并不重要。)
我正在寻找对查询的修改,如果某个事件在上个月开始,则会在月初阻止日期,但是它的长度会将其转换为以下内容。
例如 - 在上面的示例中,27日的事件实际上计划在数据库中持续7天,因此,如果我运行MONTH(start_date) = '08'
的查询,我想说前两个日期被阻止out,他们目前不会,因为阻止它的开始日期不在被选中的月份。
我很确定那里有一个子查询或其他东西可以抓住行,但我想不出来。任何人?
修改
以下Salman的答案在我想要的指示中指出了我,并且我想出了这个作为从上个月获得结转的一种方式,以剩余天数显示为本月的“第一”:
SELECT IF(MONTH(start_date) < '08', '2012-08-01', start_date) AS starter,
IF(MONTH(start_date) < '08', duration - DATEDIFF('2012-08-01',start_date), duration) AS duration
FROM EVENTS
WHERE YEAR(start_date) = '2012'
AND (MONTH(start_date) = '08' OR MONTH(start_date + INTERVAL duration DAY) = '08')
显然PHP中有很多变量需要替换,所以也许还有更好的方法吗?
答案 0 :(得分:3)
原始答案:
假设有问题的月份为2012-07
,您需要此查询:
SELECT column1, column2, columnN
FROM `events`
WHERE `start_date` <= '2012-07-01'
AND `start_date` + INTERVAL `duration` DAY > '2012-07-01'
ORDER BY start_date
修订答案:
显然,您需要一个检查重叠(或冲突)日期的查询。示例日期为2012-07-01
到2012-08-01
,查询为:
SELECT *
FROM events
WHERE '2012-08-01' > start_date
AND start_date + INTERVAL duration DAY > '2012-07-01'
ORDER BY start_date
要约束开始日期和间隔,您可以使用SELECT ... CASE
声明:
SELECT
CASE
WHEN start_date < '2012-07-01' THEN '2012-07-01'
ELSE start_date
END AS start_date_copy,
CASE
WHEN start_date < '2012-07-01' THEN duration - DATEDIFF('2012-07-01', start_date)
ELSE duration
END AS duration_copy,
FROM ...
答案 1 :(得分:0)
我正在寻找的答案,感谢其他贡献者指出我正确的方向并让我解决它!
这是基于$ yyyy和$ mm来自PHP(在我的情况下,进入函数调用),并选择单独的行而不是分组:
SELECT start_date, duration
FROM reservations
WHERE YEAR(start_date) = '".$yyyy."'
AND MONTH(start_date) = '".$mm."'
UNION
SELECT '".$yyyy."-".$mm."-01',
duration - DATEDIFF('".$yyyy."-".$mm."-01',start_date)
FROM reservations
WHERE YEAR(start_date) = '".$yyyy."'
AND MONTH(start_date) < '".$mm."'
AND MONTH(start_date + INTERVAL duration DAY) = '".$mm."'
ORDER BY start_date