带有子查询的 SQL Server 视图 - 如何拆分为单独的查询

问题描述 投票:0回答:1

我继承了一个我不理解的复杂的(对我而言)SQL Server 视图。对于查询中发生的情况,我希望得到一些建议。我还想将查询分解为单独的查询,以便我可以更好地了解发生了什么。

嵌套的 select 语句真的让我很困惑。

例如如何拆分最里面的 select 语句。

select t.OrderID, t.SampleNumber, t.Matrix, t.CustomerSampleNumber, t.TestGroup, t.[Priority], t.CustomerID, t.CustomerContact, t.SignOffDate, t.SignOff, t.[Text], 
t.Method, t.OrderDetails_User2, t.Commnt, t.OrderDueDate, t.ReportedDate, t.DueDateFlag, t.ReceiveDate, t.TAT, t.Test, t.[Param], t.ResultStatus, t.CustomerName, t.CountOfSampleNumber, t.expDueDate
from    (
            select t1.OrderID, t1.SampleNumber, t1.Matrix, t1.CustomerSampleNumber, t1.TestGroup, t1.[Priority], t1.CustomerID, t1.CustomerContact, 
            t1.SignOffDate, t1.SignOff, t1.[Text], t1.Method, t1.OrderDetails_User2, t1.Commnt, t1.OrderDueDate, t1.ReportedDate, t1.DueDateFlag, 
            t1.ReceiveDate, t1.TAT, t1.Test, t1.[Param], t1.ResultStatus, t1.CustomerName, t1.CountOfSampleNumber, t1.expDueDate, 
            rnb = row_number() over (partition by t1.OrderID, t1.SampleNumber, t1.Matrix, t1.CustomerSampleNumber, t1.TestGroup, 
            t1.[Priority], t1.CustomerID, t1.CustomerContact, t1.SignOffDate, t1.SignOff, t1.[Text], t1.Method, t1.OrderDetails_User2, 
            t1.Commnt, t1.OrderDueDate, t1.ReportedDate, t1.DueDateFlag, t1.ReceiveDate, t1.TAT, t1.Test, t1.[Param], t1.ResultStatus, 
            t1.CustomerName, t1.CountOfSampleNumber order by t1.expDueDate)
            from            (
                                select  *, 
                                        expDueDate  = cast(dateadd(day, t1.TAT + t2.num, t1.ReceiveDate) as date)
                                from    (
                                            select distinct
                                                OrderID                 = o.OrderID, 
                                                SampleNumber            = od.SampleNumber, 
                                                Matrix                  = od.Matrix, 
                                                CustomerSampleNumber    = od.CustomerSampleNumber, 
                                                TestGroup               = sd.TestGroup, 
                                                [Priority]              = o.[Priority], 
                                                CustomerID              = o.CustomerID, 
                                                CustomerContact         = o.CustomerContact, 
                                                SignOffDate             = o.SignOffDate, 
                                                SignOff                 = o.SignOff, 
                                                [Text]                  = p.[Text], 
                                                Method                  = sd.Method, 
                                                OrderDetails_User2      = od.OrderDetails_User2, 
                                                Commnt                  = o.Commnt, 
                                                OrderDueDate            = o.OrderDueDate, 
                                                ReportedDate            = o.ReportedDate, 
                                                DueDateFlag             = sd.DueDateFlag, 
                                                ReceiveDate             = od.ReceiveDate, 
                                                TAT                     = p.TAT, 
                                                Test                    = r.Test,
                                                [Param]                 = r.[Param], 
                                                ResultStatus            = r.ResultStatus, 
                                                CustomerName            = c.CustomerName, 
                                                CountOfSampleNumber     = qpsn.CountOfSampleNumber
                                            from            SMSU.Orders                         o
                                                inner join  SMSU.OrderDetails                   od      on od.OrderID = o.OrderID
                                                inner join  SMSU.SampleDetails                  sd      on sd.SampleNumber = od.SampleNumber
                                                inner join  SMSU.Priorities                     p       on p.[Priority] = o.[Priority]
                                                inner join  SMSU.Results                        r       on r.Test = sd.Test and r.SampleNumber = sd.SampleNumber and r.ORderId = sd.OrderId
                                                inner join  SMSU.Customers                      c       on c.CustomerID = o.CustomerID
                                                inner join  dbo.GC_qryParametersStillNeeded_01  qpsn    on qpsn.OrderID = o.OrderID
                                            WHERE r.ResultStatus = 0

                                    )   t1
                                    cross join  (
                                                    select top 50  -- <-- limit of days was 730
                                                        num = row_number() over (order by (select NULL)) - 1
                                                    from Information_Schema.columns
                                                )   t2
                            )                   t1
                left join   dbo.GC_tblHolidays  o   on o.HolidayDate between t1.ReceiveDate and dateadd(day, t1.TAT + t1.num, t1.ReceiveDate) and DATENAME(dw, o.HolidayDate) not in ('Saturday','Sunday') 
            group by t1.OrderID, t1.SampleNumber, t1.Matrix, t1.CustomerSampleNumber, t1.TestGroup, t1.[Priority], t1.CustomerID, t1.CustomerContact, t1.SignOffDate, t1.SignOff, t1.[Text], t1.Method, t1.OrderDetails_User2, t1.Commnt, t1.OrderDueDate, t1.ReportedDate, t1.DueDateFlag, t1.ReceiveDate, t1.TAT, t1.Test, t1.[Param], t1.ResultStatus, t1.CustomerName, t1.CountOfSampleNumber, t1.expDueDate    
            having DATEDIFF(dd, ReceiveDate, expDueDate) - (DATEDIFF(wk, ReceiveDate, expDueDate) * 2) - (CASE WHEN DATENAME(dw, ReceiveDate) = 'Sunday' THEN 1 ELSE 0 END) - (CASE WHEN DATENAME(dw, expDueDate) = 'Saturday' THEN 1 ELSE 0 END) - COUNT(o.HolidayDate) = t1.TAT AND CAST(t1.expDueDate as date) < GETDATE()
            )   t
where t.rnb = 1
sql-server subquery
1个回答
0
投票

出于分析目的,消除所有枚举列有助于减少混乱并使查询更易于管理。经过一些清理和重新格式化后的结果(不再有效的 SQL)将类似于:

select
    t.*many*
from (
    select
        t1.*many*
        rnb = row_number() over (partition by t1.*many* order by t1.expDueDate)
    from (
        select
            *many*, 
            expDueDate = cast(dateadd(day, t1.TAT + t2.num, t1.ReceiveDate) as date)
        from (
            select distinct
                o.*many*,
                od.*many*,
                sd.*many*,
                p.*many*,
                r.*many*,
                c.*many*,
                qpsn.CountOfSampleNumber
            from SMSU.Orders              o
            inner join SMSU.OrderDetails  od on od.OrderID = o.OrderID
            inner join SMSU.SampleDetails sd on sd.SampleNumber = od.SampleNumber
            inner join SMSU.Priorities    p  on p.[Priority] = o.[Priority]
            inner join SMSU.Results       r  on r.Test = sd.Test and r.SampleNumber = sd.SampleNumber and r.ORderId = sd.OrderId
            inner join SMSU.Customers     c  on c.CustomerID = o.CustomerID
            inner join dbo.GC_qryParametersStillNeeded_01 qpsn on qpsn.OrderID = o.OrderID
            WHERE r.ResultStatus = 0
        ) t1
        cross join (
            select top 50 -- <-- limit of days was 730
                num = row_number() over (order by (select NULL)) - 1
            from Information_Schema.columns
        ) t2
    ) t1
    left join dbo.GC_tblHolidays o
        on o.HolidayDate between t1.ReceiveDate and dateadd(day, t1.TAT + t1.num, t1.ReceiveDate)
        and DATENAME(dw, o.HolidayDate) not in ('Saturday','Sunday') 
    group by t1.*many*
    having DATEDIFF(dd, ReceiveDate, expDueDate)
               - (DATEDIFF(wk, ReceiveDate, expDueDate) * 2)
               - (CASE WHEN DATENAME(dw, ReceiveDate) = 'Sunday' THEN 1 ELSE 0 END)
               - (CASE WHEN DATENAME(dw, expDueDate) = 'Saturday' THEN 1 ELSE 0 END)
               - COUNT(o.HolidayDate)
           = t1.TAT
    AND CAST(t1.expDueDate as date) < GETDATE()
) t
where t.rnb = 1

据我所见:

  1. 最里面的查询是从一组连接表中进行的典型选择。我的猜测是,这会为每个样本细节生成一行。
  2. 下一级交叉连接与数字序列生成器
    1..50
    (原为
    1..730
    ),并根据内部查询结果和序列号的每个组合计算candidate
    expDueDate
    。我的猜测是,我们正在寻找一个特定的“到期”日期,但不知道如何直接计算它。相反,我们正在生成一系列日期,以最终找到符合我们的截止日期标准的日期。
  3. 下一个级别使用连接与假期表和分组的组合来计算给定日期范围内的假期数。它还计算经过的工作日(总经过的天数减去周末和假期)并过滤结果经过的工作日
    = t1.TAT
    。 (我猜测
    TAT
    是结果被视为逾期之前的工作日数)。
  4. 对于步骤 2 中生成的所有 candidate
    expDueDate
    值,步骤 3 应消除除一个或几个之外的所有值。
  5. 为了将其减少到每个样本细节最多一个,
    rnb = row_number() over (...)
    where t.rnb = 1
    的组合将为每个样本细节选择最早的合格
    expDueDate

我相信这一切都是为了根据已过的工作日来识别过期的样本详细信息。

我的总体印象是,这是可怕的(并且可能效率低下)代码(可能会起作用),但是必须有更好的方法,可能使用几个交叉应用和更有效地使用日历表。

© www.soinside.com 2019 - 2024. All rights reserved.