在SQL Server CTE中使用date参数

时间:2017-04-06 16:01:49

标签: sql-server tsql reporting-services parameters

我正在尝试在T-SQL公用表表达式中使用开始和结束日期参数。我是SQL Server开发的新手,我不确定我在查询中缺少什么。

我可以指定@startdate&的值@enddate并获得正确的结果。

但是,我正在试图弄清楚如何打开这两个参数,以便用户可以指定开始和结束日期值。该查询将用于SSRS报告中。

DECLARE @startdate Datetime,
        @enddate Datetime;

SET @startdate = '2017-02-09';
SET @enddate = '2017-02-10';

WITH ManHours AS 
( 
    SELECT DISTINCT 
        a.plant_name AS Plant, SUM(tc.total_hr) AS TotalHours
    FROM 
        area AS a 
    INNER JOIN 
        tf_department AS dep ON a.plant_id = dep.plant_id 
    INNER JOIN 
        tf_timecard AS tc ON dep.department_id = tc.department_id
    WHERE 
        tc.timecard_dt BETWEEN @startdate AND @enddate
        AND tc.department_id IN (266, 453, ...endlessly long list of IDs......)
        AND tc.hourtype_id = 1
    GROUP BY 
        a.plant_name),
Tonnage AS 
( 
    SELECT DISTINCT 
        a.plant_name AS Plant, SUM(tglt.postqty) AS TotalTonnage
    FROM 
        area AS a 
    INNER JOIN 
        plantgl AS pgl ON a.plant_id = pgl.plant_id 
    INNER JOIN 
        tgltransaction AS tglt ON pgl.glacckey = tglt.glacctkey
    WHERE 
        tglt.postdate BETWEEN @startdate AND @enddate
    GROUP BY 
        a.plant_name
)
SELECT DISTINCT 
    ManHours.Plant, 
    SUM(TotalTonnage) as 'Production Tons' , 
    SUM(TotalHours) as 'Man Hours', 
    TotalTonnage / TotalHours AS TonsPerManHour
FROM 
    ManHours 
LEFT OUTER JOIN 
    Tonnage ON ManHours.Plant = tonnage.Plant
GROUP BY 
    ManHours.Plant, ManHours.TotalHours, Tonnage.TotalTonnage

1 个答案:

答案 0 :(得分:0)

以下是您可以使用的存储过程的示例。另外,我提供了CTE中指定的“无休止的长ID列表”的两种替代方法。在我看来,最好将这个逻辑从查询中拉出来并将其放在存储过程的开头。这将使您或其他人可以轻松返回并修改此列表如果/当更改时。更好的是,我提供了一个TABLE VARIABLE(@ListOfDeptIdsFromTable),您可以使用它来实际检索此数据,而不是对字符串进行硬编码。

CREATE PROCEDURE Report
    @startdate DATETIME,
    @enddate DATETIME
AS
BEGIN

    SET NOCOUNT ON;

    DECLARE @ListOfDeptIds VARCHAR(MAX) = '266, 453, ...endlessly long list of IDs......';

    DECLARE @ListOfDeptIdsFromTable TABLE
    (
        department_id INT
    )

    INSERT INTO @ListOfDeptIdsFromTable (department_id)
    SELECT department_id
    FROM -- Table here
    WHERE -- Where credentials to retrieve the long list

    WITH ManHours AS 
    ( 
        SELECT DISTINCT 
            a.plant_name AS Plant, SUM(tc.total_hr) AS TotalHours
        FROM 
            area AS a 
        INNER JOIN 
            tf_department AS dep ON a.plant_id = dep.plant_id 
        INNER JOIN 
            tf_timecard AS tc ON dep.department_id = tc.department_id
        WHERE 
            tc.timecard_dt BETWEEN @startdate AND @enddate
            AND tc.department_id IN (@ListOfDeptIds) -- or ... IN (SELECT department_id FROM @ListOfDeptIdsFromTable)
            AND tc.hourtype_id = 1
        GROUP BY 
            a.plant_name),
    Tonnage AS 
    ( 
        SELECT DISTINCT 
            a.plant_name AS Plant, SUM(tglt.postqty) AS TotalTonnage
        FROM 
            area AS a 
        INNER JOIN 
            plantgl AS pgl ON a.plant_id = pgl.plant_id 
        INNER JOIN 
            tgltransaction AS tglt ON pgl.glacckey = tglt.glacctkey
        WHERE 
            tglt.postdate BETWEEN @startdate AND @enddate
        GROUP BY 
            a.plant_name
    )
    SELECT DISTINCT 
        ManHours.Plant, 
        SUM(TotalTonnage) as 'Production Tons' , 
        SUM(TotalHours) as 'Man Hours', 
        TotalTonnage / TotalHours AS TonsPerManHour
    FROM 
        ManHours 
    LEFT OUTER JOIN 
        Tonnage ON ManHours.Plant = tonnage.Plant
    GROUP BY 
        ManHours.Plant, ManHours.TotalHours, Tonnage.TotalTonnage

END
GO