将递归查询与非递归查询相结合

时间:2014-08-18 21:04:52

标签: sql ssms

我创建了两个查询 - 一个是递归的,一个不是 - 我希望将它们组合成一致查询(使用left join将非递归查询连接到递归一) - 但我不知道如何去做。我尝试将递归的封装到一个巨大的括号中,但这似乎不起作用。

递归查询

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)
    )

    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] /*Half minute*/
                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_Papers c, tbl_PaperEvents 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]

非重复查询

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

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))

我希望看到结果

DayReport /*From Recursive Query (which can be matched to the Non-Recursive Query)*/ | TimeReport /*From Recursive Query*/ | TimeEntryTotalHours /*From Non-Recursive Query*/
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
8/14/2014                                                                            | 1                                   | 2

1 个答案:

答案 0 :(得分:0)

只需将它们组合起来:

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] /*Half minute*/
                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_Papers c, tbl_PaperEvents 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))

)
SELECT 
Times.DayReport,
Times.TimeReport,
OtherQuery.TimeEntryTotalHours
FROM
        Times LEFT JOIN OtherQuery ON Times.DayReport = OtherQuery.[Time]

基本上,您可以向WITH子句添加更多CTE,用逗号分隔每个