2

我有以下查询。它提取发票和时间条目,并按月计算每个客户的 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
4

1 回答 1

2

您发布的 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

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

于 2013-09-05T13:01:07.750 回答