下个月的第一年周年纪念日

时间:2016-04-20 23:22:11

标签: mysql sql

我正在尝试制作一个SQl命令但没有成功:

WITH `params` AS (
SELECT DATEADD(MONTH, 1, CURRENT_TIMESTAMP) AS `nextmonth`
)
SELECT COUNT(*)
FROM `params` CROSS JOIN `Subscribers`
WHERE MONTH(`start_date`) = MONTH(`nextmonth`) AND
YEAR(`start_date`) = YEAR(`nextmonth`) - 1

它旨在为客户提供下个月的第一年周年纪念。但相反,我得到一个语法错误。

善良的灵魂会帮助我找出我做错的地方吗?

提前致谢

2 个答案:

答案 0 :(得分:1)

我的建议...编写谓词以引用Subscribers表中的“bare column”start_date。

并使用表达式获取要返回的订阅者的start_date的下限和上限。

假设“下个月”是2016年5月。

下个月将拥有1周年纪念日的订阅者是2015年5月获得start_date的订阅者。

示例查询返回COUNT(*)。我建议,为了开发查询和测试,我们可能希望从每个订阅者返回start_date以验证我们是否获得了正确的结果。

我将以这种形式编写查询:

 SELECT s.*
   FROM `Subscribers` s
  WHERE s.start_date >=  dateexpr1 
    AND s.end_date   <   dateexpr2

对于dateexpr1,我会使用像

这样的东西
DATE_FORMAT(NOW(),'%Y-%m-01') + INTERVAL -11 MONTH

对于datexpr2,我会使用

DATE_FORMAT(NOW(),'%Y-%m-01') + INTERVAL -10 MONTH

我们可以测试那些表达式......

SELECT NOW()
     , DATE_FORMAT(NOW(),'%Y-%m-01') + INTERVAL -11 MONTH AS lb
     , DATE_FORMAT(NOW(),'%Y-%m-01') + INTERVAL -10 MONTH AS ub

返回:

NOW()                lb          ub          
-------------------  ----------  ----------
2016-04-20 23:54:32  2015-05-01  2015-06-01   

如果这个月是2016年4月,那么下个月就是2016年5月。2015年5月的某个时候,所有“下个月一周年纪念”的订阅者都不会有start_date吗?

 SELECT s.*
   FROM `Subscribers` s
  WHERE s.start_date >= DATE_FORMAT(NOW(),'%Y-%m-01') + INTERVAL -11 MONTH
    AND s.start_date <  DATE_FORMAT(NOW(),'%Y-%m-01') + INTERVAL -10 MONTH

我就是这样做的。

就MySQL性能而言,这种模式(使用带有裸列的谓词)将使MySQL能够有效地使用对start_date作为前导列的索引进行范围扫描操作。

如果我们想将那些混乱的表达式移到内联视图中,我们可以这样做:

 SELECT s.*
   FROM ( SELECT DATE_FORMAT(NOW(),'%Y-%m-01') + INTERVAL -11 MONTH AS lb
        ) p
   JOIN `Subscribers` s
     ON s.start_date >= p.lb
    AND s.start_date <  p.lb + INTERVAL 1 MONTH

答案 1 :(得分:0)

WITH 'params' AS (
SELECT MONTH(DATEADD(MONTH, 1, GetDate()) AS 'nextmonth'
,YEAR(DATEADD(MONTH, 1, GetDate()) AS 'nextyear'
)
SELECT COUNT(*)
FROM `params` CROSS JOIN `Subscribers`
WHERE MONTH(`start_date`) = 'nextmonth' AND
YEAR(`start_date`) = 'nextyear'

我假设您的'start_date'是周年纪念日的字段。