我继承了一个我不理解的复杂的(对我而言)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)将类似于:
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..50
(原为1..730
),并根据内部查询结果和序列号的每个组合计算candidateexpDueDate
。我的猜测是,我们正在寻找一个特定的“到期”日期,但不知道如何直接计算它。相反,我们正在生成一系列日期,以最终找到符合我们的截止日期标准的日期。= t1.TAT
。 (我猜测 TAT
是结果被视为逾期之前的工作日数)。expDueDate
值,步骤 3 应消除除一个或几个之外的所有值。rnb = row_number() over (...)
和 where t.rnb = 1
的组合将为每个样本细节选择最早的合格 expDueDate
。我相信这一切都是为了根据已过的工作日来识别过期的样本详细信息。
我的总体印象是,这是可怕的(并且可能效率低下)代码(可能会起作用),但是必须有更好的方法,可能使用几个交叉应用和更有效地使用日历表。