【发布时间】:2018-03-16 17:01:09
【问题描述】:
我想出了一个非常简单的例子来演示我要解决的问题。
我需要选择客户合同...
1) 已过期或将在未来三个月内过期
与
2) 尚未签订新合同。
所有过期的合同与新合同一起保留在表格中。
根据这些业务规则,我对测试数据的预期结果将是返回合同 ID 6(客户 3),因为它是过期合同,没有新合同,而合同 ID 7(客户 4)少于 3运行几个月。
我查看了一些解决方案是将表连接到自身的示例
例如how do I query sql for a latest record date for each user
我想我可以只为每个客户选择最近的合同,然后像这样检查它的到期日期,但它只返回合同 ID 6 而不是我期望的 7。我正在使用 SQL 2008 R2。
有什么想法我会出错吗?
SELECT [ContractID]
,[StartDate]
,[ExpiryDate]
,TC.[CustomerID]
FROM [Test].[dbo].[TestContract] TC
inner join
(
select CustomerID,
MAX(ExpiryDate) as MaxDate
From Test.dbo.TestContract
Group by CustomerID
)CM on TC.CustomerID = CM.CustomerID and TC.ExpiryDate = CM.MaxDate
Where TC.ExpiryDate < DateAdd(DAY, 30, GETDATE())
这是我的测试数据
ContractID StartDate ExpiryDate CustomerID
1 2017-02-01 00:00:00.000 2018-02-01 00:00:00.000 1
2 2016-01-01 00:00:00.000 2017-01-01 00:00:00.000 1
4 2016-01-01 00:00:00.000 2017-11-01 00:00:00.000 2
5 2017-11-01 00:00:00.000 2018-11-01 00:00:00.000 2
6 2016-10-01 00:00:00.000 2017-10-01 00:00:00.000 3
7 2016-12-01 00:00:00.000 2017-12-01 00:00:00.000 4
8 2015-12-01 00:00:00.000 2016-12-01 00:00:00.000 4
9 2017-06-01 00:00:00.000 2018-06-01 00:00:00.000 5
这是重新创建我的测试表和数据的脚本。
USE [Test]
GO
/****** Object: Table [dbo].[TestContract] Script Date: 10/05/2017 17:07:33 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[TestContract](
[ContractID] [int] IDENTITY(1,1) NOT NULL,
[StartDate] [datetime] NOT NULL,
[ExpiryDate] [datetime] NOT NULL,
[CustomerID] [int] NOT NULL,
CONSTRAINT [PK_TestContract] PRIMARY KEY CLUSTERED
(
[ContractID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[TestContract] ON
INSERT [dbo].[TestContract] ([ContractID], [StartDate], [ExpiryDate], [CustomerID]) VALUES (1, CAST(0x0000A70D00000000 AS DateTime), CAST(0x0000A87A00000000 AS DateTime), 1)
INSERT [dbo].[TestContract] ([ContractID], [StartDate], [ExpiryDate], [CustomerID]) VALUES (2, CAST(0x0000A58000000000 AS DateTime), CAST(0x0000A6EE00000000 AS DateTime), 1)
INSERT [dbo].[TestContract] ([ContractID], [StartDate], [ExpiryDate], [CustomerID]) VALUES (4, CAST(0x0000A58000000000 AS DateTime), CAST(0x0000A81E00000000 AS DateTime), 2)
INSERT [dbo].[TestContract] ([ContractID], [StartDate], [ExpiryDate], [CustomerID]) VALUES (5, CAST(0x0000A81E00000000 AS DateTime), CAST(0x0000A98B00000000 AS DateTime), 2)
INSERT [dbo].[TestContract] ([ContractID], [StartDate], [ExpiryDate], [CustomerID]) VALUES (6, CAST(0x0000A69200000000 AS DateTime), CAST(0x0000A7FF00000000 AS DateTime), 3)
INSERT [dbo].[TestContract] ([ContractID], [StartDate], [ExpiryDate], [CustomerID]) VALUES (7, CAST(0x0000A6CF00000000 AS DateTime), CAST(0x0000A83C00000000 AS DateTime), 4)
INSERT [dbo].[TestContract] ([ContractID], [StartDate], [ExpiryDate], [CustomerID]) VALUES (8, CAST(0x0000A56100000000 AS DateTime), CAST(0x0000A6CF00000000 AS DateTime), 4)
INSERT [dbo].[TestContract] ([ContractID], [StartDate], [ExpiryDate], [CustomerID]) VALUES (9, CAST(0x0000A78500000000 AS DateTime), CAST(0x0000A8F200000000 AS DateTime), 5)
SET IDENTITY_INSERT [dbo].[TestContract] OFF
【问题讨论】:
-
你的预期输出是什么
-
@TheGameiswar 问题中写有 :) ID 6 和 7
-
Anagha 选择了我的愚蠢错误。 30 应该是 90。我现在用我的真实数据去测试它,这显然会更复杂。感谢大家提出的解决方案。我只需要一个有效的:) 我会看看我是否能理解你所描述的,因为我确信那里有很好的学习机会。 .
标签: sql-server