30/60/90天Sumation查询

时间:2013-09-04 12:58:02

标签: sql sql-server-2005 join

我有以下查询。它提取发票和时间条目,并按月计算每个客户的EHR(有效小时费率)。我需要得到的是:

    company ,agreement ,lastMonthEHR,60dayEHR,90dayEHR,6MoEHR,12MoEHR,LifeEHR
    CompanyA,AgreementB,       30.45,   27.76,   55.22, 30.75,  30.00,  25.00 

编辑:

我为格式道歉。我会看看我是否可以更好地格式化它。以下查询返回月度发票,并计算EHR。

    SELECT a.AGR_Name, AGR_Type.AGR_Type_Desc, c.Company_Name, ap.InvoiceDate,ap.Revenue,ap.Hours,ap.EHR
    FROM AGR_Header AS a INNER JOIN Company AS c ON a.Company_RecID = c.Company_RecID
    LEFT JOIN AGR_Type ON a.AGR_Type_RecID = AGR_Type.AGR_Type_RecID
    LEFT JOIN (
      SELECT ar.AGR_Header_RecID,ar.Revenue,ac.InvoiceDate,ISNULL (ac.Hours, 0) AS Hours,
      CASE
           WHEN ac.Hours IS NULL THEN (ar.Revenue)
           WHEN ac.Hours <= 1 THEN (ar.Revenue)
           ELSE CAST (ar.Revenue / NULLIF (ac.Hours,0) as NUMERIC (9,2))
      END AS 'EHR'
      FROM (
        SELECT ah.AGR_Header_RecID,
        DATEADD(month,ai.Month_Nbr-1,dateadd(year,ai.Year_Nbr-2000,'2000-01-01')) as InvoiceDate,
        CAST (ai.Monthly_Inv_Amt AS NUMERIC (9, 2)) AS Revenue
        FROM
        dbo.AGR_Header AS ah INNER JOIN
        dbo.AGR_Invoice_Amt AS ai ON ah.AGR_Header_RecID = ai.AGR_Header_RecID
        GROUP BY ah.AGR_Header_RecID, ai.Month_Nbr, ai.Year_Nbr) as ar
      LEFT JOIN (
        SELECT ah.AGR_Header_RecID,SUM(te.Hours_Actual) AS Hours, dateadd(month, datediff(month,0,te.Date_start),0) as InvoiceDate
        FROM
        dbo.Time_Entry AS te INNER JOIN 
        dbo.AGR_Header AS ah ON te.Agr_Header_RecID = ah.AGR_Header_RecID
        WHERE (te.Agr_Header_RecID IS NOT NULL) AND (te.Agr_Hours IS NOT NULL)
       GROUP BY ah.AGR_Header_RecID, dateadd(month, datediff(month,0,te.Date_Start),0)) AS ac ON ar.AGR_Header_RecID = ac.AGR_Header_RecID
    AND ar.InvoiceDate = ac.InvoiceDate) AS ap ON ap.AGR_Header_RecID = a.AGR_Header_RecID
    ORDER BY Company, Agreement, InvoiceDate

1 个答案:

答案 0 :(得分:1)

您发布的SQL非常复杂,但我认为它可以简化。我认为关键是将发票数据转换为与以下类似的格式:

DECLARE @invoice AS TABLE(
    [ID] INT, 
    [CompanyID] INT,
    [InvoiceDate] DATE, 
    [Hours] DECIMAL(9,2), 
    [Revenue] DECIMAL(9,2))

从那里开始,计算非常简单,并且可以使用CASE WHEN语句以最小的子选择来完成(为了清晰起见,我只使用了一个,但即使是那个也可以消除)。这是SQL Server的完整工作示例:

--Setup table and dummy data
DECLARE @invoice AS TABLE(
    [ID] INT, 
    [CompanyID] INT,
    [InvoiceDate] DATE, 
    [Hours] DECIMAL(9,2), 
    [Revenue] DECIMAL(9,2))
INSERT INTO @invoice VALUES(1, 1, '2013-01-01', 5, 100)
INSERT INTO @invoice VALUES(2, 1, '2013-02-01', 6, 100)
INSERT INTO @invoice VALUES(3, 1, '2013-03-01', 7, 100)
INSERT INTO @invoice VALUES(4, 1, '2013-04-01', 8, 100)
INSERT INTO @invoice VALUES(5, 1, '2013-05-01', 9, 100)
INSERT INTO @invoice VALUES(6, 1, '2013-06-01', 10, 100)
INSERT INTO @invoice VALUES(7, 1, '2013-07-01', 11, 100)
INSERT INTO @invoice VALUES(8, 1, '2013-08-01', 12, 100)
INSERT INTO @invoice VALUES(9, 2, '2013-04-01', 5, 100)
INSERT INTO @invoice VALUES(10, 2, '2013-05-01', 6, 100)
INSERT INTO @invoice VALUES(11, 2, '2013-06-01', 7, 100)
INSERT INTO @invoice VALUES(12, 2, '2013-07-01', 8, 100)

--Calculate last month start and end dates
--Hardcoded here for brevity
DECLARE @lastMonthStartDate AS DATETIME
DECLARE @lastMonthEndDate AS DATETIME
SET @lastMonthStartDate = '2013-08-01'
SET @lastMonthEndDate = '2013-09-01'

--Calculate EHRs for different time periods
SELECT
    A.CompanyID,
    CASE WHEN A.LastMonthHours = 0 THEN 0 ELSE A.LastMonthRevenue / A.LastMonthHours END as [LastMonthEHR],
    CASE WHEN A.Last60DaysHours = 0 THEN 0 ELSE A.Last60DaysRevenue / A.Last60DaysHours END as [Last60DaysEHR],
    CASE WHEN A.Last90DaysHours = 0 THEN 0 ELSE A.Last90DaysRevenue / A.Last90DaysHours END as [Last90DaysEHR]
FROM (
SELECT 
    [CompanyID],
    SUM(CASE WHEN [InvoiceDate] >= @lastMonthStartDate AND [InvoiceDate] < @lastMonthEndDate THEN [Hours] ELSE 0 END) as [LastMonthHours],
    SUM(CASE WHEN [InvoiceDate] >= @lastMonthStartDate AND [InvoiceDate] < @lastMonthEndDate THEN [Revenue] ELSE 0 END) as [LastMonthRevenue],
    SUM(CASE WHEN [InvoiceDate] >= DATEADD(d, -60, GETDATE()) THEN [Hours] ELSE 0 END) as [Last60DaysHours],
    SUM(CASE WHEN [InvoiceDate] >= DATEADD(d, -60, GETDATE()) THEN [Revenue] ELSE 0 END) as [Last60DaysRevenue],
    SUM(CASE WHEN [InvoiceDate] >= DATEADD(d, -90, GETDATE()) THEN [Hours] ELSE 0 END) as [Last90DaysHours],
    SUM(CASE WHEN [InvoiceDate] >= DATEADD(d, -90, GETDATE()) THEN [Revenue] ELSE 0 END) as [Last90DaysRevenue]
FROM @invoice
GROUP BY [CompanyID]
) A

我认为这种方法对您有用。我知道我必须简单地解决问题,以便说明我在答案中处理这样的查询的方式,所以如果你需要我扩展它,请告诉我。