【问题标题】:Join three SQL Server CTEs加入三个 SQL Server CTE
【发布时间】:2019-08-28 08:39:16
【问题描述】:

我已经为此工作了一段时间,我想我快要完成了。我设法找到了一种使用 CTE a 和 b 以及内部联接的方法来合并我的两个结果。我也在寻找一种可能的方法来将我的运行平均列 (c) 添加到这个结果中。但我尝试的任何方法似乎都不起作用。任何有关我应该如何执行此操作或更理想的处理方式的指导将不胜感激。

图片:

ALTER FUNCTION [dbo].[fn_rptAppointmentsBreakdown2]
    (@startDate DATETIME, 
     @endDate DATETIME) 
RETURNS TABLE 
AS
    RETURN 
        (WITH a AS
         (
             SELECT 
                 calendar_date,
                 SUM(cIsFS + cIsGB + cIsCH+ cIsGC + cIsWM + cIsTC + cIsAR + cIsPP + cIsC3 + cIsPW) AS 'TotalBookedPRU', 
                 SUM(cShowedUp * cIsFS) + SUM(cShowedUp * cIsCH) +
                     SUM(cShowedUp * cIsPW) AS Showed,
                 NULL AS 'Total Booked',
                 SUM(cIsNoShow * cIsC3) + SUM(cIsNoShow * cIsPW) AS 'No Shows/ Rebooked'
             FROM 
                 reports.dbo.vw_Appointments a
             WHERE
                 cAppointmentType = 'Recalls' AND
                 CONVERT(DATETIME, CONVERT(VARCHAR(8), calendar_date, 112)) BETWEEN @startDate AND @endDate 
             GROUP BY 
                 calendar_date
         ),
         b AS
         (
             SELECT 
                 calendar_date,
                 NULL AS 'Total Booked pru',    
                 NULL AS Showed,
                 SUM(cIsFS + cIsGB + cIsCH+ cIsGC + cIsWM + cIsTC + cIsAR + cIsPP + cIsC3 + cIsPW) AS 'TotalBooked',    
                 NULL AS 'No Shows/ Rebooked'
             FROM 
                 reports.dbo.vw_Appointments a
             WHERE
                 CONVERT(DATETIME, CONVERT(VARCHAR(8), calendar_date, 112)) BETWEEN @startDate AND @endDate 
             GROUP BY 
                 calendar_date
        ),
        c AS 
        (
             SELECT 
                 a.*, a2.Running_Average AS runningaverage
             FROM
                 a 
             OUTER APPLY
                 (SELECT AVG(showed) AS Running_Average
                  FROM a a2
                  WHERE a2.calendar_date <= a.calendar_date) a2
        )
        SELECT 
            a.calendar_date,
            a.TotalBookedPRU,
            a.Showed,
            b.TotalBooked
        FROM 
            a 
        INNER JOIN 
            b ON a.calendar_date = b.calendar_date
    )

【问题讨论】:

  • @Larnu - 2008 年没有。ROWS UNBOUNDED PRECEDING 等是在 SQL Server 2012 中引入的
  • 只是升级@MartinSmith 的众多原因之一。 (加上它即将完全用完支持的事实)。确实让我感到惊讶的是,有多少人仍在使用如此接近生命终结的东西。

标签: sql-server tsql sql-server-2008 common-table-expression stored-functions


【解决方案1】:

您有三个 cte,例如 abc

  • cte c 未在您粘贴的函数代码中使用。所以最好去掉不用的代码,让代码更清晰,更容易理解
  • 在底部SELECT,您只选择了四个字段,例如calendar_date, TotalBookedPRU, Showed, TotalBooked,因此我们可以只选择SELECT statement 中的字段
  • 添加了计算时间的列RunningTime

    ALTER FUNCTION [dbo].[fn_rptAppointmentsBreakdown2](@startDate datetime
    , @endDate datetime) RETURNS TABLE AS
    RETURNS TABLE 
    AS
    RETURN
    (
    with a as (
       SELECT 
       calendar_date,
       SUM(cIsFS + cIsGB + cIsCH+ cIsGC + cIsWM + cIsTC + cIsAR + cIsPP + cIsC3 + cIsPW) 
           AS 'TotalBookedPRU',     
       Null AS 'Total Booked'   
       FROM reports.dbo.vw_Appointments ACTION
       WHERE
       cAppointmentType = 'Recalls' AND
       CONVERT(datetime, CONVERT(varchar(8),calendar_date,112)) 
           BETWEEN @startDate AND @endDate    
       GROUP BY 
       calendar_date
       ),
    b as (
        SELECT 
        calendar_date,
        null AS 'Total Booked pru', 
        null AS Showed,
        SUM(cIsFS + cIsGB + cIsCH+ cIsGC + cIsWM + cIsTC + cIsAR + cIsPP + cIsC3 
            + cIsPW) AS 'TotalBooked'   
        FROM reports.dbo.vw_Appointments a
        WHERE   CONVERT(datetime, CONVERT(varchar(8),calendar_date,112)) 
            BETWEEN @startDate AND @endDate    
        GROUP BY 
        calendar_date
    )
    
    declare @start datetime = getutcdate();  
    
    SELECT 
    a.calendar_date,
    a.TotalBookedPRU,
    a.Showed,
    b.TotalBooked
    , DATEDIFF(ms, @start, getutcdate()) RunningTime
    FROM a Inner join b ON a.calendar_date = b.calendar_date
    )
    

另外,如果你想知道需要多少次执行你的查询和硬盘输入/输出/读取操作的计数,你可以使用:

SET STATISTICS TIME ON
SET STATISTICS IO ON 
GO
SELECT * FROM fn_rptAppointmentsBreakdown2(/*your parameters here*/)
SET STATISTICS TIME OFF
SET STATISTICS IO OFF 

【讨论】:

    猜你喜欢
    • 2019-10-05
    • 2017-05-07
    • 1970-01-01
    • 2015-08-19
    • 1970-01-01
    • 2018-03-20
    • 2020-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多