【发布时间】:2012-01-16 03:55:10
【问题描述】:
我有这个不那么规范化的表:
ItemName Type DateTransferred
Hand Drill IN 2012-01-16 11:06:10.077
Hand Drill OUT 2012-01-16 11:06:16.563
Hand Drill IN 2012-01-16 11:06:26.780
Grinder IN 2012-01-16 11:06:33.917
Hand Drill OUT 2012-01-16 11:06:45.443
创建查询:
CREATE TABLE [dbo].[TransferLog](
[ItemName] [nvarchar](50) NOT NULL,
[Type] [nvarchar](3) NOT NULL,
[DateTransferred] [datetime] NOT NULL
) ON [PRIMARY]
ALTER TABLE [dbo].[TransferLog]
ADD CONSTRAINT [DF_TransferLog_DateTransferred]
DEFAULT (getdate()) FOR [DateTransferred]
基本上,上表记录了项目团队从仓库借入的物品(类型:IN)和退回的物品(类型:OUT)。
我想要实现的是获得所有借来的设备,当它被借用(IN)和它被归还(OUT)时。尝试将“借用交易”与其对应的“退货交易”匹配时会出现问题,因为它们唯一的关系是 ItemName:
选择所有“借用交易”:
select tIn.ItemName, tIn.DateTransferred as DateBorrowed
from transferLog as tIn
where tIn.[type] = 'IN'
结果:
ItemName DateBorrowed
Hand Drill 2012-01-16 11:06:10.077
Hand Drill 2012-01-16 11:06:26.780
Grinder 2012-01-16 11:06:33.917
尝试选择所有“借来的交易”及其对应的“归还交易”:
select tIn.ItemName, tIn.DateTransferred as DateBorrowed,
tOut.DateTransferred as DateReturned
from transferLog as tIn
left join transferLog as tOut
on tIn.ItemName = tOut.ItemName
and tOut.[type] = 'OUT'
where tIn.[type] = 'IN'
结果:
ItemName DateBorrowed DateReturned
Hand Drill 2012-01-16 11:06:10.077 2012-01-16 11:06:16.563
Hand Drill 2012-01-16 11:06:10.077 2012-01-16 11:06:45.443
Hand Drill 2012-01-16 11:06:26.780 2012-01-16 11:06:16.563
Hand Drill 2012-01-16 11:06:26.780 2012-01-16 11:06:45.443
Grinder 2012-01-16 11:06:33.917 NULL
注意,每个“借来的交易”应该只有一个或没有对应的“退货交易”,上面的结果将每个“借来的交易”与每一个“退货交易”匹配,只要它们具有相同的ItemName。结果应该是:
ItemName DateBorrowed DateReturned
Hand Drill 2012-01-16 11:06:10.077 2012-01-16 11:06:16.563
Hand Drill 2012-01-16 11:06:26.780 2012-01-16 11:06:45.443
Grinder 2012-01-16 11:06:33.917 NULL
现在,我正在考虑如何将“退货交易”与大于且最接近“借用交易”的 DateTransferred 的DateTransferred 匹配。比如:
select tIn.ItemName, tIn.DateTransferred as DateBorrowed,
tOut.DateTransferred as DateReturned
from transferLog as tIn
left join transferLog as tOut
on tIn.ItemName = tOut.ItemName
and tOut.[type] = 'OUT'
and
tOut.DateTransferred > tIn.DateTransferred
-- AND NEAREST tOut.DateTransferred TO tIn.DateTransferred
where tIn.[type] = 'IN'
我读过这个(SQL Join on Nearest less than date)和这个(Join tables on nearest date in the past, in MySQL)但是子查询对我来说是一个困难的选择,因为我需要的查询结果只是另一个查询的一部分,我担心它会影响性能。
【问题讨论】:
标签: sql-server-2005 join