所以如果我修改你的SQL,我可以看到它的层:
Select
ROW_NUMBER() OVER (
PARTITION BY x.LMID
ORDER BY (
SELECT
MIN(val)
FROM (
VALUES
( ABS(DATEDIFF(DD, rh.OpenDT, x.Booked))),
( ABS(DATEDIFF(DD, rh.CloseDT, x.Booked)))
) AS value(val)
), v.LastVersion DESC
) AS RowNum
,(
SELECT
MIN(val)
FROM (
VALUES
( ABS(DATEDIFF(DD, rh.OpenDT, x.Booked))),
( ABS(DATEDIFF(DD, rh.CloseDT, x.Booked)))
) AS value(val)
)
FROM (
SELECT
lm.LMID
,lm.ID
,lm.Booked
,req.RequestId AS RequestID
FROM #Pop as lm
INNER JOIN dbo.request as req
ON req.ServicerLoanNumber = lm.ID
INNER JOIN dbo.RequestHistory as rh
ON rh.RequestId = req.RequestId
AND req.LastVersion = rh.Version
AND ( rh.FinalDispositionTypeId = 1 OR
rh.RequestStatusTypeId = 20 )
WHERE lm.Booked >= lm.AddDate
AND YEAR(lm.Booked) >= 2013
) as x
INNER JOIN dbo.Request as v
ON v.RequestId = x.RequestID
INNER JOIN dbo.RequestHistory as rh
ON rh.RequestId = v.RequestId
AND rh.Version = v.LastVersion;
因此,您有一个显示在T-SQL中的临时表和两个dbo表.
因此,我们可以制作一些伪表作为CTE来对此进行一些测试:
with pop(lmid, id, booked, AddDate) as (
select * from values
(1,10,'2023-11-14'::date, '2023-11-14'::date)
), request(ServicerLoanNumber, RequestId, LastVersion) as (
select * from values
(10,100, 1000)
),RequestHistory(RequestId, version, FinalDispositionTypeId, RequestStatusTypeId, opendt, closedt) as (
select * from values
(100, 1000, 1, 0, '2023-11-14'::date, '2023-11-14'::date)
)
Select
ROW_NUMBER() OVER (
PARTITION BY x.LMID
ORDER BY (
SELECT
MIN(val)
FROM (
VALUES
( ABS(DATEDIFF(DD, rh.OpenDT, x.Booked))),
( ABS(DATEDIFF(DD, rh.CloseDT, x.Booked)))
) AS value(val)
), v.LastVersion DESC
) AS RowNum
,(
SELECT
MIN(val)
FROM (
VALUES
( ABS(DATEDIFF(DD, rh.OpenDT, x.Booked))),
( ABS(DATEDIFF(DD, rh.CloseDT, x.Booked)))
) AS value(val)
)
FROM (
SELECT
lm.LMID
,lm.ID
,lm.Booked
,req.RequestId
FROM Pop as lm
INNER JOIN request as req
ON req.ServicerLoanNumber = lm.ID
INNER JOIN RequestHistory as rh
ON rh.RequestId = req.RequestId
AND req.LastVersion = rh.Version
AND ( rh.FinalDispositionTypeId = 1 OR
rh.RequestStatusTypeId = 20 )
WHERE lm.Booked >= lm.AddDate
AND YEAR(lm.Booked) >= 2013
) as x
INNER JOIN Request as v
ON v.RequestId = x.RequestID
INNER JOIN RequestHistory as rh
ON rh.RequestId = v.RequestId
AND rh.Version = v.LastVersion;
给出错误:
VALUES子句中的表达式[ABS(DATE_DETATEINDAYS("2023 -11- 14","2023-11- 14"))]无效
这是有意义的,因为Snowflake只接受值中的常量表达式.
因此,如果我们开始移动代码以便于查看代码链,则可以将子 Select x
移动到CTE中:
with pop(lmid, id, booked, AddDate) as (
select * from values
(1,10,'2023-11-14'::date, '2023-11-14'::date)
), request(ServicerLoanNumber, RequestId, LastVersion) as (
select * from values
(10,100, 1000)
),RequestHistory(RequestId, version, FinalDispositionTypeId, RequestStatusTypeId, opendt, closedt) as (
select * from values
(100, 1000, 1, 0, '2023-11-14'::date, '2023-11-14'::date)
), cte_x as (
SELECT
lm.LMID
,lm.ID
,lm.Booked
,req.RequestId
FROM Pop as lm
INNER JOIN request as req
ON req.ServicerLoanNumber = lm.ID
INNER JOIN RequestHistory as rh
ON rh.RequestId = req.RequestId
AND req.LastVersion = rh.Version
AND ( rh.FinalDispositionTypeId = 1 OR
rh.RequestStatusTypeId = 20 )
WHERE lm.Booked >= lm.AddDate
AND YEAR(lm.Booked) >= 2013
)
Select
ROW_NUMBER() OVER (
PARTITION BY x.LMID
ORDER BY (
SELECT
MIN(val)
FROM (
VALUES
( ABS(DATEDIFF(DD, rh.OpenDT, x.Booked))),
( ABS(DATEDIFF(DD, rh.CloseDT, x.Booked)))
) AS value(val)
), v.LastVersion DESC
) AS RowNum
,(
SELECT
MIN(val)
FROM (
VALUES
( ABS(DATEDIFF(DD, rh.OpenDT, x.Booked))),
( ABS(DATEDIFF(DD, rh.CloseDT, x.Booked)))
) AS value(val)
)
FROM cte_x as x
INNER JOIN Request as v
ON v.RequestId = x.RequestID
INNER JOIN RequestHistory as rh
ON rh.RequestId = v.RequestId
AND rh.Version = v.LastVersion;
现在这个块重复两次,所以这可以做一次(这也是问题所在)
SELECT
MIN(val)
FROM (
VALUES
( ABS(DATEDIFF(DD, rh.OpenDT, x.Booked))),
( ABS(DATEDIFF(DD, rh.CloseDT, x.Booked)))
) AS value(val)
无论如何,如果这是固定的,我们可以交换到最小值而不是最小值:
LEAST( ABS(DATEDIFF(DD, rh.OpenDT, x.Booked)),
ABS(DATEDIFF(DD, rh.CloseDT, x.Booked)))
如果任何输入为空,则Lest表现不佳,因此,只要所有三个值(Booked、opendt、Closedt)都不为空,这是安全的,
因此,它可以写成:
with pop(lmid, id, booked, AddDate) as (
select * from values
(1,10,'2023-11-14'::date, '2023-11-14'::date)
), request(ServicerLoanNumber, RequestId, LastVersion) as (
select * from values
(10,100, 1000)
),RequestHistory(RequestId, version, FinalDispositionTypeId, RequestStatusTypeId, opendt, closedt) as (
select * from values
(100, 1000, 1, 0, '2023-11-14'::date, '2023-11-14'::date)
), cte_x as (
SELECT
lm.LMID
,lm.ID
,lm.Booked
,req.RequestId
FROM Pop as lm
INNER JOIN request as req
ON req.ServicerLoanNumber = lm.ID
INNER JOIN RequestHistory as rh
ON rh.RequestId = req.RequestId
AND req.LastVersion = rh.Version
AND ( rh.FinalDispositionTypeId = 1 OR
rh.RequestStatusTypeId = 20 )
WHERE lm.Booked >= lm.AddDate
AND YEAR(lm.Booked) >= 2013
)
Select
ROW_NUMBER() OVER (
PARTITION BY x.LMID
ORDER BY LEAST( ABS(DATEDIFF(DD, rh.OpenDT, x.Booked)),
ABS(DATEDIFF(DD, rh.CloseDT, x.Booked))), v.LastVersion DESC
) AS RowNum
,LEAST( ABS(DATEDIFF(DD, rh.OpenDT, x.Booked)),
ABS(DATEDIFF(DD, rh.CloseDT, x.Booked))) as min_days
FROM cte_x as x
INNER JOIN Request as v
ON v.RequestId = x.RequestID
INNER JOIN RequestHistory as rh
ON rh.RequestId = v.RequestId
AND rh.Version = v.LastVersion;
这提供了:
这就是我所期望的,我不喜欢做最少的两次,我倾向于这样做是CTE,但我假设还需要更复杂的逻辑,它已经被剥离,所以就不说了.