簡體   English   中英

SQL 查詢選擇前 14 個月,如果缺少任何月份,則添加金額“0”

[英]SQL query to select previous 14 months where add amount '0' if any month is missing

我創建了這個查詢來選擇前 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 月。

您可以首先生成月份和年份,然后可以將其與您的查詢結合起來 -

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;

嘗試生成日歷日期並進行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;

創建一個帶有可能月份的選擇/聯合的臨時表,然后從該表中加入您的表,僅選擇給定月份的記錄。 為方便起見,從幾個月前計算日期范圍(但您可以在連接中使用更復雜的開始日期和結束日期表達式)。

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 作為沒有記錄的月份的續訂日期,以及為有記錄的月份找到的最小續訂日期。 不知道你到底想要什么。

對於這樣的 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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM