我正在尝试制作一个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
它旨在为客户提供下个月的第一年周年纪念。但相反,我得到一个语法错误。
善良的灵魂会帮助我找出我做错的地方吗?
提前致谢
答案 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'是周年纪念日的字段。