如何在sql中按客户的天数计算金额

时间:2018-06-13 13:33:25

标签: sql-server

我想从以下查询中使用的发票表中按天计算客户总数:我想要什么

Three table and result

第1名表:MstCustomer
第二个表名:Job_Details
第三表名称:发票

select distinct Cust.Cust_Name,
            case when DATEDIFF(dd,INV.Bill_Submit_Date,GETDATE()) > 0 and DATEDIFF(dd,INV.Bill_Submit_Date,GETDATE()) < 31
            then sum(INV.Bill_Amount) end  AS '1-30 DAYS',
            case when DATEDIFF(dd,INV.Bill_Submit_Date,GETDATE()) > 30 and DATEDIFF(dd,INV.Bill_Submit_Date,GETDATE()) < 46
            then sum(INV.Bill_Amount) end AS '31-45 DAYS',
            case when DATEDIFF(dd,Bill_Submit_Date,GETDATE()) > 45 
            then sum(INV.Bill_Amount) end AS 'ABOVE 45 DAYS',
            Balance =sum(INV.Bill_Amount) - sum(INV.Advance_Amount)

            from Invoice INV 
                               inner join Job_Details JD on JD.Job_ID= INV.Job_ID
                               inner join MstCustomer cust ON cust.Cust_ID= JD.Cust_ID

                               group by Cust.Cust_Name,Bill_Submit_Date,Bill_Amount,Advance_Amount

预期结果 Expected Result

2 个答案:

答案 0 :(得分:1)

您的查询看起来像95%,您只需将sum函数放在错误的位置:

select Cust.Cust_Name
      ,sum(case when DATEDIFF(dd,INV.Bill_Submit_Date,GETDATE()) < 31
                then INV.Bill_Amount
                else 0
                end
          )  AS [1-30 DAYS]
      ,sum(case when DATEDIFF(dd,INV.Bill_Submit_Date,GETDATE()) between 31 and 45
                then INV.Bill_Amount
                else 0
                end
          ) AS [31-45 DAYS]
      ,sum(case when DATEDIFF(dd,Bill_Submit_Date,GETDATE()) > 45 
                then INV.Bill_Amount
                else 0
                end
          ) AS [ABOVE 45 DAY]
      ,sum(INV.Bill_Amount) - sum(INV.Advance_Amount) as Balance

from Invoice INV 
    inner join Job_Details JD
        on JD.Job_ID= INV.Job_ID
    inner join MstCustomer cust
        on cust.Cust_ID= JD.Cust_ID

group by Cust.Cust_Name

答案 1 :(得分:1)

通过在子查询中执行DATEDIFF,您可以简化外部查询中的计算。

并且您想要简化CASE,而不是在CASE中使用SUM。

例如:

select 
 cust.Cust_Name as "Customer Name",
 SUM(CASE WHEN q.Days_Submitted BETWEEN 1 AND 30 THEN q.Bill_Amount END) AS "1-30 Days Amount",
 SUM(CASE WHEN q.Days_Submitted BETWEEN 31 AND 45 THEN q.Bill_Amount END) AS "31-45 Days Amount",
 SUM(CASE WHEN q.Days_Submitted > 45 THEN q.Bill_Amount END) AS "Above 45 Days Amount",
 SUM(q.Bill_Amount - q.Advance_Amount) AS Balance
from 
(
   select 
    JD.Cust_ID,
    DATEDIFF(dd, INV.Bill_Submit_Date, GetDate()) as Days_Submitted,
    SUM(INV.Bill_Amount) as Bill_Amount,
    SUM(INV.Advance_Amount) as Advance_Amount
   from Invoice INV
   join Job_Details JD on (JD.Job_ID = INV.Job_ID)
   where DATEDIFF(dd, INV.Bill_Submit_Date, GetDate()) > 0
   group by JD.Cust_ID, DATEDIFF(dd, INV.Bill_Submit_Date, GetDate())
) as q
join MstCustomer cust on (cust.Cust_ID = q.Cust_ID)
group by cust.Cust_Name
order by cust.Cust_Name;

测试代码段

--
-- Sample Data
--
declare @MstCustomer table (Cust_ID int primary key, Cust_Name varchar(30));
declare @Job_Details  table (Job_ID int primary key, Cust_ID int);
declare @Invoice table (Invoice_ID int identity(1,1) primary key, Job_ID int, Invoice_No varchar(30), Bill_Amount int, Advance_Amount int, Bill_Date date, Bill_Submit_Date date);
insert into @MstCustomer (Cust_ID, Cust_Name) values (1,'ABC'), (2,'DEF'), (3,'GHI'), (4,'JKL');
insert into @Job_Details (Job_ID, Cust_ID) values (1,1), (2,2), (3,3), (4,4);
insert into @Invoice (Job_ID, Invoice_No, Bill_Amount, Advance_Amount, Bill_Date, Bill_Submit_Date) values 
 (1,'7/18-19',300,100,GetDate(),GetDate())
,(1,'6/18-19',6000,1000,GetDate(),GetDate()-46)
,(1,'5/18-19',5000,0,GetDate(),GetDate()-46)
,(1,'4/18-19',4000,0,GetDate(),GetDate()-32)
,(1,'3/18-19',3000,0,GetDate(),GetDate()-32)
,(1,'2/18-19',2000,500,GetDate(),GetDate()-1)
,(1,'1/18-19',1000,500,GetDate(),GetDate()-1)

;

--
-- Query
--
select 
 cust.Cust_Name as "Customer Name",
 SUM(CASE WHEN q.Days_Submitted BETWEEN 1 AND 30 THEN q.Bill_Amount END) AS "1-30 Days Amount",
 SUM(CASE WHEN q.Days_Submitted BETWEEN 31 AND 45 THEN q.Bill_Amount END) AS "31-45 Days Amount",
 SUM(CASE WHEN q.Days_Submitted > 45 THEN q.Bill_Amount END) AS "Above 45 Days Amount",
 SUM(q.Bill_Amount - q.Advance_Amount) AS Balance
from 
(
   select 
    JD.Cust_ID,
    DATEDIFF(dd, INV.Bill_Submit_Date, GetDate()) as Days_Submitted,
    SUM(INV.Bill_Amount) as Bill_Amount,
    SUM(INV.Advance_Amount) as Advance_Amount
   from @Invoice INV
   join @Job_Details JD on (JD.Job_ID = INV.Job_ID)
   where DATEDIFF(dd, INV.Bill_Submit_Date, GetDate()) > 0
   group by JD.Cust_ID, DATEDIFF(dd, INV.Bill_Submit_Date, GetDate())
) as q
join @MstCustomer cust on (cust.Cust_ID = q.Cust_ID)
group by cust.Cust_Name
order by cust.Cust_Name;

<强>结果:

Customer Name 1-30 Days Amount 31-45 Days Amount Above 45 Days Amount Balance
------------- ---------------- ----------------- -------------------- -------
ABC                       3000              7000                11000   19000