【问题标题】:Adding in A Recursive Query to a Combined Group of Queries that has a Declare将递归查询添加到具有声明的组合查询组
【发布时间】:2014-08-20 23:29:44
【问题描述】:

我正在尝试将另一个查询添加到这个巨大的查询折叠中 - 除了最后一部分 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

【问题讨论】:

  • 是的,您不能将声明语句放在 CTE 中。你必须找到另一种方法。也许将“anotherQuery”变成填充表变量或临时表而不是 CTE 的代码。

标签: sql sql-server tsql


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    您应该将所有声明移到顶部。就像 Tab 说的,你不能在 CTE 中声明一个变量。不确定他对其余部分的意思,您可以在顶部声明变量,然后在任何您希望的地方使用它们

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-16
      • 2011-08-05
      • 1970-01-01
      • 2021-04-07
      • 2015-05-05
      • 2016-01-23
      • 2015-08-11
      • 1970-01-01
      相关资源
      最近更新 更多