我很难写好标题,所以我会在这里详细描述这个问题。
我们有表[dbo]。[LEASE_APPLICATIONS_AUDIT_LOG],用于存储更改日期时间的历史数据。如果数据的状态不是IN('E','F','I','O','X')那么这意味着它在那时被批准,如果状态不是这些那些,然后它没有被批准。它可以被批准,也不会以任何顺序和多次批准。例如:
'2010.01.01', 'A'
'2010.02.01', 'B'
'2010.03.01', 'E'
'2010.04.01', 'Z'
这意味着该记录从2010.01.01至2010.03.01获得批准,然后在2010.04.01再次获得批准。
还有另一个表[dbo]。[LEASE_FINANCING_AUDIT_LOG],用于存储当时的基本付款金额。例如,如果对于相同的记录,我会有这样的条目:
'2010.01.01', 123
'2010.04.01', 321
那么这意味着从2010.01.01到2010.03.01(未经批准)从基本付款是123,然后从2010.04.01起,价值变为321。
可能存在各种状态更改组合,并且在任何时间段都可能存在不同的基本支付值。
因此,目标是找到介于APPROVED期间的最新base_payment值。
以下是我们迄今为止制作的脚本。有2个表格,包含该数据和功能。其他代码片段来自单元测试,这就是为什么它们是这样的,如果逻辑不是预期的那样,它们将输出'bad'字符串。该功能正在运行,但我不太喜欢TOP 1 / ORDER BY方法,并试图找出是否有更好的方法来实现这一点。有什么想法吗?
SET NOCOUNT ON;
CREATE TABLE [dbo].[LEASE_APPLICATIONS_AUDIT_LOG]
(
[LEASE_APPLICATION] CHAR(8)
, [APPLICATION_STATUS_CODE] CHAR(1)
, [CHANGED_DATE] DATETIME2(7) NOT NULL
);
GO
CREATE TABLE [dbo].[LEASE_FINANCING_AUDIT_LOG]
(
[LEASE_APPLICATION] CHAR(8)
, [BASE_PAYMENT] DECIMAL(10, 2) NULL
, [CHANGED_DATE] DATETIME2(7) NOT NULL
);
GO
CREATE FUNCTION [dbo].[post_approval_payment_amount] (@lease_application CHAR(8))
RETURNS TABLE
AS
RETURN (
SELECT TOP 1 lfal.BASE_PAYMENT AS post_approval_payment_amount
FROM LEASE_APPLICATIONS_AUDIT_LOG laal
CROSS APPLY
(
SELECT TOP 1 lf.BASE_PAYMENT
FROM LEASE_FINANCING_AUDIT_LOG lf
WHERE lf.LEASE_APPLICATION = laal.LEASE_APPLICATION
AND lf.CHANGED_DATE < COALESCE((
SELECT TOP 1 la.CHANGED_DATE
FROM LEASE_APPLICATIONS_AUDIT_LOG la
WHERE la.LEASE_APPLICATION = laal.LEASE_APPLICATION
AND la.CHANGED_DATE > laal.CHANGED_DATE
ORDER BY la.CHANGED_DATE
), CAST('9999-12-31 23:59:59' AS DATETIME))
ORDER BY lf.CHANGED_DATE DESC
) lfal
WHERE laal.LEASE_APPLICATION = @lease_application
AND laal.APPLICATION_STATUS_CODE NOT IN ('E', 'F', 'I', 'O', 'X')
ORDER BY laal.CHANGED_DATE DESC
);
GO
DECLARE @lease_application CHAR(8) = '35163328'
, @base_payment DECIMAL = 209.12
, @expected DECIMAL = 209.12
, @actual DECIMAL;
DECLARE @la AS TABLE
(
change_date DATETIME2(7)
, application_status_code CHAR(1) NULL
, base_amount DECIMAL NULL
, is_laal BIT
);
INSERT INTO @la ( change_date
, application_status_code
, base_amount
, is_laal
)
VALUES ('2017-05-11 03:46:26.4800000', 'K', NULL, 1)
, ('2017-05-11 03:48:05.0600000', NULL, @base_payment, 0)
, ('2017-06-21 14:07:51.2200000', 'X', NULL, 1);
INSERT INTO dbo.lease_applications_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, APPLICATION_STATUS_CODE
)
SELECT @lease_application
, l.change_date
, l.application_status_code
FROM @la AS l
WHERE l.is_laal = 1;
INSERT INTO dbo.lease_financing_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, BASE_PAYMENT
)
SELECT @lease_application
, l.change_date
, l.base_amount
FROM @la AS l
WHERE l.is_laal = 0;
SELECT @actual = post_approval_payment_amount
FROM [dbo].[post_approval_payment_amount](@lease_application);
IF (@expected <> @actual) SELECT 'Test 1 failed'
ELSE SELECT 'Test 1 passed';
SELECT @lease_application = '30000152'
, @base_payment = 622.15
, @expected = 622.15;
DELETE FROM @la;
INSERT INTO @la ( change_date
, application_status_code
, base_amount
, is_laal
)
VALUES ('2017-05-11 03:46:26.4800000', 'z', NULL, 1)
, ('2017-05-11 03:48:05.0600000', NULL, @base_payment, 0);
INSERT INTO dbo.lease_applications_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, APPLICATION_STATUS_CODE
)
SELECT @lease_application
, l.change_date
, l.application_status_code
FROM @la AS l
WHERE l.is_laal = 1;
INSERT INTO dbo.lease_financing_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, BASE_PAYMENT
)
SELECT @lease_application
, l.change_date
, l.base_amount
FROM @la AS l
WHERE l.is_laal = 0;
SELECT @actual = post_approval_payment_amount
FROM [dbo].[post_approval_payment_amount](@lease_application);
IF (@expected <> @actual) SELECT 'Test 2 failed'
ELSE SELECT 'Test 2 passed';
SELECT @lease_application = '38768578'
, @base_payment = 453.70
, @expected = NULL
, @actual = NULL;
DELETE FROM @la;
INSERT INTO @la ( change_date
, application_status_code
, base_amount
, is_laal
)
VALUES ('2017-05-11 03:46:26.4800000', 'L', NULL, 1)
, ('2017-06-09 12:00:36.2000000', 'X', NULL, 1)
, ('2017-06-12 03:48:05.0600000', NULL, @base_payment, 0);
INSERT INTO dbo.lease_applications_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, APPLICATION_STATUS_CODE
)
SELECT @lease_application
, l.change_date
, l.application_status_code
FROM @la AS l
WHERE l.is_laal = 1;
INSERT INTO dbo.lease_financing_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, BASE_PAYMENT
)
SELECT @lease_application
, l.change_date
, l.base_amount
FROM @la AS l
WHERE l.is_laal = 0;
SELECT @actual = post_approval_payment_amount
FROM [dbo].[post_approval_payment_amount](@lease_application);
IF (@actual IS NOT NULL) SELECT 'Test 3 failed'
ELSE SELECT 'Test 3 passed';
SELECT @lease_application = '38282661'
, @base_payment = 451.25
, @expected = 451.25;
DELETE FROM @la;
INSERT INTO @la ( change_date
, application_status_code
, base_amount
, is_laal
)
VALUES ('2017-05-11 03:46:26.4800000', 'O', NULL, 1)
, ('2017-05-11 03:48:05.0600000', NULL, @base_payment, 0)
, ('2017-07-05 10:52:14.6800000', 'O', NULL, 1)
, ('2017-07-05 11:10:24.0400000', 'E', NULL, 1)
, ('2017-07-05 11:10:25.6000000', 'E', NULL, 1)
, ('2017-07-05 11:10:49.1900000', 'L', NULL, 1)
, ('2017-07-06 00:04:30.6400000', 'O', NULL, 1);
INSERT INTO dbo.lease_applications_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, APPLICATION_STATUS_CODE
)
SELECT @lease_application
, l.change_date
, l.application_status_code
FROM @la AS l
WHERE l.is_laal = 1;
INSERT INTO dbo.lease_financing_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, BASE_PAYMENT
)
SELECT @lease_application
, l.change_date
, l.base_amount
FROM @la AS l
WHERE l.is_laal = 0;
SELECT @actual = post_approval_payment_amount
FROM [dbo].[post_approval_payment_amount](@lease_application);
IF (@expected <> @actual) SELECT 'Test 4 failed'
ELSE SELECT 'Test 4 passed';
SELECT @lease_application = '38768578'
, @base_payment = 453.70
, @expected = 453.70;
DELETE FROM @la;
INSERT INTO @la ( change_date
, application_status_code
, base_amount
, is_laal
)
VALUES ('2017-05-11 03:46:26.4800000', 'L', NULL, 1)
, ('2017-05-11 03:48:05.0600000', NULL, 200, 0)
, ('2017-05-12 03:48:05.0600000', NULL, @base_payment, 0)
, ('2017-06-09 12:00:36.2000000', 'X', NULL, 1)
, ('2017-09-18 11:57:13.5100000', NULL, 100, 0);
INSERT INTO dbo.lease_applications_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, APPLICATION_STATUS_CODE
)
SELECT @lease_application
, l.change_date
, l.application_status_code
FROM @la AS l
WHERE l.is_laal = 1;
INSERT INTO dbo.lease_financing_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, BASE_PAYMENT
)
SELECT @lease_application
, l.change_date
, l.base_amount
FROM @la AS l
WHERE l.is_laal = 0;
SELECT @actual = post_approval_payment_amount
FROM [dbo].[post_approval_payment_amount](@lease_application);
IF (@expected <> @actual) SELECT 'Test 5 failed'
ELSE SELECT 'Test 5 passed';
SELECT @lease_application = '38768578'
, @base_payment = 453.70
, @expected = 453.70;
DELETE FROM @la;
INSERT INTO @la ( change_date
, application_status_code
, base_amount
, is_laal
)
VALUES ('2017-05-11 03:46:26.4800000', 'L', NULL, 1)
, ('2017-05-11 03:48:05.0600000', NULL, @base_payment, 0)
, ('2017-06-09 12:00:36.2000000', 'X', NULL, 1)
, ('2017-09-18 11:57:13.5100000', NULL, 100, 0);
INSERT INTO dbo.lease_applications_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, APPLICATION_STATUS_CODE
)
SELECT @lease_application
, l.change_date
, l.application_status_code
FROM @la AS l
WHERE l.is_laal = 1;
INSERT INTO dbo.lease_financing_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, BASE_PAYMENT
)
SELECT @lease_application
, l.change_date
, l.base_amount
FROM @la AS l
WHERE l.is_laal = 0;
SELECT @actual = post_approval_payment_amount
FROM [dbo].[post_approval_payment_amount](@lease_application);
IF (@expected <> @actual) SELECT 'Test 6 failed'
ELSE SELECT 'Test 6 passed';
DROP TABLE [dbo].[LEASE_APPLICATIONS_AUDIT_LOG];
GO
DROP TABLE [dbo].[LEASE_FINANCING_AUDIT_LOG];
GO
DROP FUNCTION [dbo].[post_approval_payment_amount];
GO
答案 0 :(得分:0)
你问了一些关于替代方法的想法。您可以单独或组合使用这些想法:
ON LEASE_APPLICATIONS_AUDIT_LOG.CHANGED_DATE <= LEASE_FINANCING_AUDIT_LOG.CHANGED_DATE
。CAST('9999-12-31 23:59:59' AS DATETIME
默认值的便利位置。