将递归查询添加到具有声明的组合查询组

时间:2014-08-20 15:09:50

标签: sql sql-server tsql

我正在尝试向这个巨大的查询片段添加另一个查询 - 除了最后一部分anotherQuery之外一切正常 - 我已经分别编写了anotherQuery,然后尝试将其与其他人一起粉碎但是 - 产生一个错误,读取DECLARE附近的'不正确的语法。期待'('或SELECT'

如果没有声明,我不确定如何重写它?或者,如果我能找到我的错误?

DECLARE
    @UserId BIGINT = 31946,
    @StartDateOfWeek DATETIME = '8/4/2014',
    @EndDateOfWeek DATETIME = '8/10/2014'


;WITH
    Dates (D) AS 
    (

        SELECT 0 UNION ALL
        SELECT 1 + D FROM Dates WHERE D < DATEDIFF(DD, @StartDateOfWeek, @EndDateOfWeek)
    ),
    Times AS (
    SELECT
        CAST([Date] as DATE) [DayReport],
        SUM([TotalHours]) [TimeReport]
    FROM
    (
        SELECT
             DD2.[Date],
            0 [TotalHours]
        FROM
        (
            SELECT
                DATEADD(DD, D, @StartDateOfWeek) [Date]
            FROM
                Dates
        ) DD2
        UNION 
        SELECT
            [Date],
            SUM([RealMinutes])/60 [TotalHours]
        FROM
        (
            SELECT
                CAST(EventCreateDate AS DATE) [Date],
                CASE
                    WHEN [Minutes] >= 30 AND CAST([Minutes] AS FLOAT)/CAST([PageCount] AS FLOAT) >= 1 THEN 
                    CASE WHEN CAST([PageCount] AS FLOAT) * 0.5 > 45 THEN 45 ELSE CAST([PageCount] AS FLOAT) * 0.5 END 
                    WHEN [Minutes] >= 60 AND CAST([Minutes] AS FLOAT)/CAST([PageCount] AS FLOAT) < 1 THEN 60
                        ELSE
                    [Minutes] 
            END [RealMinutes]
            FROM
        (
            SELECT
                CASE WHEN c.[PageCount] = 0 THEN 1 WHEN c.[PageCount] IS NULL THEN 1 ELSE c.[PageCount] END [PageCount],
                ev.EventCreateDate, 
                DATEDIFF(MI, ev.EventCreateDate, ev.EventCompletionDate) [MINUTES]
            FROM 
                tbl_Charts c, tbl_WFChartEvents ev, tbl_Users u
            WHERE
                c.ChartId = ev.ChartId

            AND CAST(ev.EventCreateDate AS DATE) BETWEEN CAST(@StartDateOfWeek AS DATE) AND CAST(@EndDateOfWeek AS DATE)
            AND ev.EventCreateUserId = @UserId
            AND ev.EventId = 201 
            AND u.UserId = ev.EventCreateUserId
        ) TC
    ) TH
    GROUP BY
        [Date]
) TF
GROUP BY
    [Date])

,


otherQuery AS ( SELECT
        CAST ([TimeEntryDate] as DATE) [Time]
        ,DATEDIFF(HH, [TimeEntryStartTime], [TimeEntryEndTime]) AS TimeEntryTotalHours
    FROM 
        [tbl_TimeEntries] te
        INNER JOIN tbl_Users u ON u.UserId = te.[TimeEntryUserId]
        INNER JOIN tbl_UserPermissions up ON up.UserId = u.UserId
        INNER JOIN tbl_Permissions p ON p.PermissionId = up.PermissionId
        LEFT OUTER JOIN tbl_ApprovalStatuses ast ON ast.ApprovalStatusId = te.TimeEntryStatusId 
    WHERE
        (@UserId = te.[TimeEntryUserId] OR @UserId = -1)
        AND p.PermissionType = 'Coder'
        AND((te.[TimeEntryStartTime] BETWEEN  @StartDateOfWeek AND @EndDateOfWeek) OR  (@StartDateOfWeek IS NULL))
        Group By [TimeEntryDate],[TimeEntryStartTime],[TimeEntryEndTime]

)

,

anotherQuery AS ( 

DECLARE @insertedDate date = @StartDateOfWeek
DECLARE @days_table TABLE (days DATE); 

WHILE @insertedDate<@EndDateOfWeek
BEGIN
INSERT INTO @days_table (days) values (@insertedDate);
set @insertedDate=DATEADD(D,1,@insertedDate)
END
INSERT INTO @days_table (days) values (@EndDateOfWeek);

WHILE @insertedDate<@EndDateOfWeek
BEGIN
INSERT INTO @days_table (days) values (@insertedDate);
set @insertedDate=DATEADD(D,1,@insertedDate)
END
INSERT INTO @days_table (days) values (@EndDateOfWeek);

SELECT days DayReport ,CASE WHEN TotalCharts IS NULL THEN 0 ELSE TotalCharts END AS TotalCharts
FROM @days_table dt
LEFT JOIN (
    SELECT Count(ChartID) TotalCharts
        ,DayReport
    FROM (
        SELECT 
            c.ChartId,
            UserId
            ,CONVERT(DATE, ev.EventCompletionDate, 102) AS DayReport
        FROM tbl_charts c, tbl_users u
        INNER JOIN tbl_wfchartevents ev ON u.userid = ev.eventcreateuserid
        WHERE ev.eventid IN (201, 301, 302, 303, 304)
            AND ev.eventstatusid IN (3)
            AND CONVERT(DATE, ev.EventCompletionDate, 102) BETWEEN @StartDateOfWeek AND @EndDateOfWeek
            AND u.userid = @UserId
            AND c.ChartId = ev.ChartId
            AND ev.EventCreateUserId = u.UserId
        ) t
    GROUP BY t.userid
        ,DayReport
    ) R ON dt.days = R.DayReport

)


SELECT 
Times.DayReport,
ISNULL(SUM(OtherQuery.TimeEntryTotalHours),0) as HoursReported,
Times.TimeReport as HoursCalculated,
ISNULL(SUM(OtherQuery.TimeEntryTotalHours),0) - Times.TimeReport as HoursVar,
CASE WHEN ISNULL(SUM(OtherQuery.TimeEntryTotalHours),0)=0 THEN 0 
WHEN ISNULL(SUM(OtherQuery.TimeEntryTotalHours),0) > 0 THEN ((Times.TimeReport)/(ISNULL(SUM(OtherQuery.TimeEntryTotalHours),0))) END as [Var %],
anotherQuery.TotalCharts
FROM
        Times LEFT JOIN OtherQuery ON Times.DayReport = OtherQuery.[Time] LEFT JOIN AnotherQuery ON Times.DayReport = AnotherQuery.DayReport
GROUP BY Times.DayReport, Times.TimeReport
ORDER BY Times.DayReport

2 个答案:

答案 0 :(得分:0)

您应该将所有DECLARES移到顶部。像Tab所说,你不能在CTE中声明一个变量。不知道他对剩下的意思是什么,你可以在顶部声明变量,并在以后的任何地方使用它们

答案 1 :(得分:0)

未经测试,但我认为它会像这样工作:

DECLARE
    @UserId BIGINT = 31946,
    @StartDateOfWeek DATETIME = '8/4/2014',
    @EndDateOfWeek DATETIME = '8/10/2014';

DECLARE @insertedDate date = @StartDateOfWeek
DECLARE @days_table TABLE (days DATE); 

WHILE @insertedDate<@EndDateOfWeek
BEGIN
INSERT INTO @days_table (days) values (@insertedDate);
set @insertedDate=DATEADD(D,1,@insertedDate)
END
INSERT INTO @days_table (days) values (@EndDateOfWeek);

WHILE @insertedDate<@EndDateOfWeek
BEGIN
INSERT INTO @days_table (days) values (@insertedDate);
set @insertedDate=DATEADD(D,1,@insertedDate)
END
INSERT INTO @days_table (days) values (@EndDateOfWeek);


WITH
    Dates (D) AS 
    (

        SELECT 0 UNION ALL
        SELECT 1 + D FROM Dates WHERE D < DATEDIFF(DD, @StartDateOfWeek, @EndDateOfWeek)
    ),
    Times AS (
    SELECT
        CAST([Date] as DATE) [DayReport],
        SUM([TotalHours]) [TimeReport]
    FROM
    (
        SELECT
             DD2.[Date],
            0 [TotalHours]
        FROM
        (
            SELECT
                DATEADD(DD, D, @StartDateOfWeek) [Date]
            FROM
                Dates
        ) DD2
        UNION 
        SELECT
            [Date],
            SUM([RealMinutes])/60 [TotalHours]
        FROM
        (
            SELECT
                CAST(EventCreateDate AS DATE) [Date],
                CASE
                    WHEN [Minutes] >= 30 AND CAST([Minutes] AS FLOAT)/CAST([PageCount] AS FLOAT) >= 1 THEN 
                    CASE WHEN CAST([PageCount] AS FLOAT) * 0.5 > 45 THEN 45 ELSE CAST([PageCount] AS FLOAT) * 0.5 END 
                    WHEN [Minutes] >= 60 AND CAST([Minutes] AS FLOAT)/CAST([PageCount] AS FLOAT) < 1 THEN 60
                        ELSE
                    [Minutes] 
            END [RealMinutes]
            FROM
        (
            SELECT
                CASE WHEN c.[PageCount] = 0 THEN 1 WHEN c.[PageCount] IS NULL THEN 1 ELSE c.[PageCount] END [PageCount],
                ev.EventCreateDate, 
                DATEDIFF(MI, ev.EventCreateDate, ev.EventCompletionDate) [MINUTES]
            FROM 
                tbl_Charts c, tbl_WFChartEvents ev, tbl_Users u
            WHERE
                c.ChartId = ev.ChartId

            AND CAST(ev.EventCreateDate AS DATE) BETWEEN CAST(@StartDateOfWeek AS DATE) AND CAST(@EndDateOfWeek AS DATE)
            AND ev.EventCreateUserId = @UserId
            AND ev.EventId = 201 
            AND u.UserId = ev.EventCreateUserId
        ) TC
    ) TH
    GROUP BY
        [Date]
) TF
GROUP BY
    [Date])

,


otherQuery AS ( SELECT
        CAST ([TimeEntryDate] as DATE) [Time]
        ,DATEDIFF(HH, [TimeEntryStartTime], [TimeEntryEndTime]) AS TimeEntryTotalHours
    FROM 
        [tbl_TimeEntries] te
        INNER JOIN tbl_Users u ON u.UserId = te.[TimeEntryUserId]
        INNER JOIN tbl_UserPermissions up ON up.UserId = u.UserId
        INNER JOIN tbl_Permissions p ON p.PermissionId = up.PermissionId
        LEFT OUTER JOIN tbl_ApprovalStatuses ast ON ast.ApprovalStatusId = te.TimeEntryStatusId 
    WHERE
        (@UserId = te.[TimeEntryUserId] OR @UserId = -1)
        AND p.PermissionType = 'Coder'
        AND((te.[TimeEntryStartTime] BETWEEN  @StartDateOfWeek AND @EndDateOfWeek) OR  (@StartDateOfWeek IS NULL))
        Group By [TimeEntryDate],[TimeEntryStartTime],[TimeEntryEndTime]

)

,

anotherQuery AS ( 
SELECT days DayReport ,CASE WHEN TotalCharts IS NULL THEN 0 ELSE TotalCharts END AS TotalCharts
FROM @days_table dt
LEFT JOIN (
    SELECT Count(ChartID) TotalCharts
        ,DayReport
    FROM (
        SELECT 
            c.ChartId,
            UserId
            ,CONVERT(DATE, ev.EventCompletionDate, 102) AS DayReport
        FROM tbl_charts c, tbl_users u
        INNER JOIN tbl_wfchartevents ev ON u.userid = ev.eventcreateuserid
        WHERE ev.eventid IN (201, 301, 302, 303, 304)
            AND ev.eventstatusid IN (3)
            AND CONVERT(DATE, ev.EventCompletionDate, 102) BETWEEN @StartDateOfWeek AND @EndDateOfWeek
            AND u.userid = @UserId
            AND c.ChartId = ev.ChartId
            AND ev.EventCreateUserId = u.UserId
        ) t
    GROUP BY t.userid
        ,DayReport
    ) R ON dt.days = R.DayReport

)


SELECT 
Times.DayReport,
ISNULL(SUM(OtherQuery.TimeEntryTotalHours),0) as HoursReported,
Times.TimeReport as HoursCalculated,
ISNULL(SUM(OtherQuery.TimeEntryTotalHours),0) - Times.TimeReport as HoursVar,
CASE WHEN ISNULL(SUM(OtherQuery.TimeEntryTotalHours),0)=0 THEN 0 
WHEN ISNULL(SUM(OtherQuery.TimeEntryTotalHours),0) > 0 THEN ((Times.TimeReport)/(ISNULL(SUM(OtherQuery.TimeEntryTotalHours),0))) END as [Var %],
anotherQuery.TotalCharts
FROM
        Times LEFT JOIN OtherQuery ON Times.DayReport = OtherQuery.[Time] LEFT JOIN AnotherQuery ON Times.DayReport = AnotherQuery.DayReport
GROUP BY Times.DayReport, Times.TimeReport
ORDER BY Times.DayReport