我已创建此查询来选择日期,前14个月的金额,在这种情况下,如果该月不存在任何记录,则该月将丢失,请建议我为该特定月份添加零和月的解决方案丢失。
SELECT dtSubscriptionRenewalDate,
DATE_FORMAT(dtSubscriptionRenewalDate, "%b %Y") AS month,
SUM(intPaymentAmount) as total
FROM `tbl_pi_payment`
WHERE strCurrencyCode = 'USD'
and dtSubscriptionRenewalDate <= NOW()
and dtSubscriptionRenewalDate >= Date_add(Now(),interval - 14 month)
group by month
ORDER BY `tbl_pi_payment`.`dtSubscriptionRenewalDate` ASC;
您可以从结果中查看,缺少2018年11月。
答案 0 :(得分:0)
您可以先生成月份和年份,然后再将其与查询结合起来-
SELECT dtSubscriptionRenewalDate,
DATE_FORMAT(dtSubscriptionRenewalDate, "%b %Y") AS month,
SUM(intPaymentAmount) as total
FROM (SELECT 'January' AS months
UNION
SELECT 'February'
UNION
SELECT 'March'
UNION
SELECT 'April'
UNION
SELECT 'May'
UNION
SELECT 'June'
UNION
SELECT 'July'
UNION
SELECT 'August'
UNION
SELECT 'September'
UNION
SELECT 'October'
UNION
SELECT 'November'
UNION
SELECT 'December') month
CROSS JOIN (SELECT 2018 AS years
UNION
SELECT 2019
UNION
SELECT 2020) year
LEFT JOIN `tbl_pi_payment` tp ON YEAR(tp.dtSubscriptionRenewalDate) = year.years
AND MONTH(tp.dtSubscriptionRenewalDate) = month.months
WHERE strCurrencyCode = 'USD'
and dtSubscriptionRenewalDate <= NOW()
and dtSubscriptionRenewalDate >= Date_add(Now(),interval - 14 month)
group by month
ORDER BY `tbl_pi_payment`.`dtSubscriptionRenewalDate` ASC;
答案 1 :(得分:0)
尝试生成日历日期并设置JOIN
CREATE TABLE daterange (dte DATE);
SET @counter := 15;
WHILE (@counter < 0) DO
INSERT daterange VALUES (SELECT DATE_SUB(CURDATE(), INTERVAL @counter:=@counter - 1 Month));
END WHILE;
SELECT dtSubscriptionRenewalDate, DATE_FORMAT(dte, "%b %Y") AS month, SUM(intPaymentAmount) as total
FROM daterange D LEFT JOIN `tbl_pi_payment` T ON T.DATE_FORMAT(dtSubscriptionRenewalDate, "%b %Y") = D.DATE_FORMAT(dte , "%b %Y")
WHERE strCurrencyCode = 'USD' and dtSubscriptionRenewalDate <= NOW() and dtSubscriptionRenewalDate >= Date_add(Now(),interval - 14 month)
GROUP BY DATE_FORMAT(dte, "%b %Y")
ORDER BY `tbl_pi_payment`.`dtSubscriptionRenewalDate` ASC;
答案 2 :(得分:0)
使用可能的月份的选择/联合创建一个临时表,然后从该表中左加入表,仅选择给定月份的记录。为了方便起见,请从几个月前的日期开始计算日期范围(但您可以只在联接中使用更复杂的表达式作为开始日期和结束日期)。
select
min(dtSubscriptionRenewalDate) as min_renewal_date,
date_format(date_sub(now(), interval months_ago month), "%b %Y") as month,
coalesce(sum(intPaymentAmount),0) as total
from (
select
months_ago,
date(date_format(date_sub(now(), interval months_ago month), "%Y-%m-01")) start_date,
date(date_format(date_sub(now(), interval months_ago-1 month), "%Y-%m-01")) end_date
from (select 0 months_ago union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9 union select 10 union select 11 union select 12 union select 13 union select 14 order by months_ago) months_ago
) date_range
left join tbl_pi_payment on
dtSubscriptionRenewalDate >= start_date and
dtSubscriptionRenewalDate < end_date and
dtSubscriptionRenewalDate <= now() and
strCurrencyCode = 'USD'
group by months_ago desc;
对于没有记录的月份,它将报告NULL作为续订日期,对于有记录的月份,将报告最小续订日期。不确定在那里到底想要什么。
答案 3 :(得分:0)
对于像这样的Oracle:
SELECT md.month AS month,
SUM(intPaymentAmount) as total
FROM `tbl_pi_payment` ,
(select add_month(trunc(sysdate,'MM')-level) month from dual connect by level <15) md
WHERE strCurrencyCode = 'USD'
trunc(dtSubscriptionRenewalDate,'MM')(+)=md.month
group by md.month
ORDER BY md.month ASC;