の間で最新のお支払い値を見つけてください。いいタイトルを書くのはかなり難しいので、ここで詳しく説明します。"有効期間"
変更された日付時刻の履歴データを保存する[dbo]。[LEASE_APPLICATIONS_AUDIT_LOG]があります。データのステータスがINではない場合( 'E'、 'F'、 'I'、 'O'、 'X')、その時点で承認されたことを意味し、ステータスがこれら以外の場合それは承認されていません。それは承認され、いかなる順序でも何度も承認されないことがあります。たとえば、次の
レコードは2010年3月1日まで2010年1月1日から承認された後、2010年4月1日で再び承認されたことを意味し'2010.01.01', 'A'
'2010.02.01', 'B'
'2010.03.01', 'E'
'2010.04.01', 'Z'
。
当時の基本支払額を保存する別のテーブル[dbo]。[LEASE_FINANCING_AUDIT_LOG]があります。例えば、私は、このようなエントリを持つことになり、同じレコードの場合:
'2010.01.01', 123
'2010.04.01', 321
そのベースの支払いから2010年3月1日まで2010年1月1日から123だったことを意味します(未承認となった)、その後、2010年4月1日からの値となりましたを321
とすることができます。ステータスの変更はさまざまな組み合わせがあり、任意の期間に異なる基本支払い値が存在する可能性があります。
したがって、目標はAPPROVED期間の間にあったLATESTのbase_payment値を見つけることです。
これまでに作成したスクリプトを以下に示します。そのデータと機能を持つ2つのテーブルがあります。他のコードスニペットは単体テストから取得されているため、それらが同じようなものであり、ロジックが期待通りでない場合は「不良」文字列を出力します。この関数は機能していますが、私は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
[sqlfiddleで質問を追跡しようとする試み](http://sqlfiddle.com/#!6/a2e96/1) –
それ以上8K文字の長さであるように私はバイオリンにそれを置くことはできません。コードを最小限に抑えようとしたときに、他の苦情がありました –
rextester.com dbfiddle.uk db-fiddle.comを試してください。あなたの質問はあまり明確ではありません。 –