我继承了一个我不理解的复杂的(对我而言)SQL Server 视图。对于查询中发生的情况,我希望得到一些建议。我还想将查询分解为单独的查询,以便我可以更好地了解发生了什么。
查询正在查找测试结果的 DueDate(计算得出)小于当前日期的记录,这意味着测试结果已过期。
它还会查看假期表以排除某些日子,以及排除周六和周日。我想。
嵌套的 select 语句真的让我很困惑。
查询非常慢,这就是为什么我需要理解然后改进或替换它。
环境是 SQL Server 数据库后端、Microsoft Access 前端。 Access 使用链接的 SQL Server 视图作为报表对象的记录源。
提前致谢!
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
去
这是示例输出。
OrderID SampleNumber 矩阵 CustomerSampleNumber TestGroup 优先级 CustomerID CustomerContact SignOffDate SignOff 文本方法 OrderDetails_User2 Commnt OrderDueDate ReportedDate DueDateFlag ReceiveDate TAT 测试参数 ResultStatus CustomerName CountOfSampleNumber expDueDate 123456 123456-02 水管第二左 NULL 0 1234567 John Do 50:52.8 1 正常 SM 2110 NULL NULL NULL NULL 0 00:00.0 10 ZZ 外观样本描述 0 Outisde Park 12 9/24/2024 123456 123456-02 水管 左第二 标准金属分析 0 1234567 John Do 50:52.8 1 正常 EPA 200.7 NULL NULL NULL NULL 0 00:00.0 10 11-铝 ICP 铝业,Al 0 Outisde Park 12 9/24/2024 123456 123456-02 水管道 第二左 标准金属分析 0 1234567 John Do 50:52.8 1 正常 EPA 200.7 NULL NULL NULL NULL 0 00:00.0 10 20-铜 by ICP Copper, Cu 0 Outisde Park 12 9/24/2024 123456 123456-02 水管道第二左标准金属分析 0 1234567 John Do 50:52.8 1 正常 EPA 200.7 NULL NULL NULL NULL 0 00:00.0 10 21-Iron by ICP Iron, Fe 0 Outisde Park 12 9/24/2024
出于分析目的,消除所有枚举列有助于减少混乱并使查询更易于管理。经过一些清理和重新格式化后的结果(不再有效的 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
),并根据内部查询结果和序列号的每个组合计算expDueDate
。我的猜测是,我们正在寻找一个特定的“到期”日期,但不知道如何直接计算它。相反,我们正在生成一系列日期,以最终找到符合我们的截止日期标准的日期。= t1.TAT
。 (我猜是结果被视为逾期之前的工作日数)。rnb = row_number() over (...)
和 where t.rnb = 1
的组合将为每个样本细节选择最早的合格 expDueDate
。我相信这一切都是为了根据已过的工作日来识别过期的样本详细信息。
我的总体印象是,这是可怕的(并且可能效率低下)代码(可能会起作用),但是必须有更好的方法,可能使用几个交叉应用和更有效地使用日历表。