我正在尝试编写Microsoft SQL Server查询,以检索文本字段相同的最旧记录,但日期间隔为30秒或更短。这是一个例子:
我的表:
RecordID TextField1 TextField2 DateField1
--------------------------------------------------------------------------------
1 SomeData1 SomeData2 9/11/2011 2:33:00pm
2 SomeData3 SomeData4 9/11/2011 2:33:15pm
3 SomeData3 SomeData4 9/11/2011 2:33:18pm
4 SomeData3 SomeData4 9/11/2011 2:42:12pm
5 SomeData1 SomeData2 9/11/2011 2:33:01pm
6 SomeData6 SomeData7 9/11/2011 2:33:01pm
7 SomeData1 SomeData2 9/12/2011 2:33:00pm
8 SomeData6 SomeData8 9/11/2011 2:33:03pm
好的,所以在这个例子中,我想要一个查询,它将拉出TextField1=TextField1
和TextField2=TextField2
的行,它们之间的日期是30秒或更短(我想要两个中最老的一行)回)。因此,在此示例中,查询应返回:
RecordID TextField1 TextField2 DateField1
--------------------------------------------------------------------------------
1 SomeData1 SomeData2 9/11/2011 2:33:00pm
2 SomeData3 SomeData4 9/11/2011 2:33:15pm
由于TextField2不同,因此未返回RecordID 8。
希望我能够清楚地解释清楚。任何帮助将不胜感激!
答案 0 :(得分:5)
我无法理解你问题的一切。
这是一个通用的SQL查询,它会将您的表的记录与同一个表进行比较,查找具有不同RecordID但等于TextField1和TextField2的记录。
如果这看起来像您想要的那样发表评论,我们可以改进此查询以获得您正在寻找的内容。
更新:
SELECT * FROM my_table AS t1
INNER JOIN my_table AS t2
ON (
t1.RecordID < t2.recordID
AND
DATEDIFF(second, t1.DateField1, t2.DateField1) <= 30
AND
t1.TextField1 = t2.TextField1
AND
t2.TextField2 = t1.TextField2
);
答案 1 :(得分:1)
这将返回您在示例中查找的两条记录。 t1
和t2
之间的联接会返回符合条件的记录,然后加入t3
会返回符合条件的最旧行。
;
with TestCTE(RecordID, TextField1, TextField2, DateField1)
as
(
select 1, 'SomeData1', 'SomeData2', cast('9/11/2011 2:33:00pm' as datetime)
union
select 2, 'SomeData3', 'SomeData4', cast('9/11/2011 2:33:15pm' as datetime)
union
select 3, 'SomeData3', 'SomeData4', cast('9/11/2011 2:33:18pm' as datetime)
union
select 4, 'SomeData3', 'SomeData4', cast('9/11/2011 2:42:12pm' as datetime)
union
select 5, 'SomeData1', 'SomeData2', cast('9/11/2011 2:33:01pm' as datetime)
union
select 6, 'SomeData6', 'SomeData7', cast('9/11/2011 2:33:01pm' as datetime)
union
select 7, 'SomeData1', 'SomeData2', cast('9/12/2011 2:33:00pm' as datetime)
union
select 8, 'SomeData6', 'SomeData8', cast('9/11/2011 2:33:03pm' as datetime)
)
select t1.*
from TestCTE t1
join TestCTE t2 on t1.RecordID <> t2.RecordID
and t1.TextField1 = t2.TextField1
and t1.TextField2 = t2.TextField2
and datediff(second, t1.DateField1, t2.DateField1) <= 30
join
(
select TextField1, TextField2, min(DateField1) as MinDate
from TestCTE
group by TextField1, TextField2
) t3 on t1.TextField1 = t3.TextField1
and t1.TextField2 = t3.TextField2
and t1.DateField1 = t3.MinDate
答案 2 :(得分:1)
听起来像一个简单的自我加入,而不是试图让它超过应有的。通过执行自联接并应用组,以下内容应该为您完成。
自我联接在两个文本字段上,第一个表的记录ID总是比第二个表中的那个大....然后,比较日期/时间因素为30秒。
由于来自ADrift的评论,并重新查看数据,我想到的是记录中的日期/时间戳字段总是会增加并非总是如此......轻微变化......获取给定text1和text2的最新日期/时间,然后重新加入以获取其余的详细信息。
select
YT3.*
from
( select
YT.TextField1,
YT.TextField2,
MIN( YT.DateField1) OldestDateTime,
from
YourTable YT
Join YourTable YT2
on YT.TextField1 = YT2.TextField1
AND YT.TextField2 = YT2.TextField2
AND YT.RecordID > YT2.RecordID
AND datediff(second, YT.DateField1, YT2.DateField1) <= 30
group by
YT.TextField1,
YT.TextFIeld2 ) PreQuery
JOIN YourTable YT3
on PreQuery.TextField1 = YT3.TextField1
AND PreQuery.TextField2 = YT3.TextField2
AND PreQuery.OldestDateTime = YT3.DateField1
order by
whatever...
答案 3 :(得分:0)
假设只有不超过两个相邻的行(彼此相距30秒以内)并且您使用的是SQL Server 2005或更高版本:
WITH sampledata (RecordID, TextField1, TextField2, DateField1) AS
(
SELECT 1, 'SomeData1', 'SomeData2', CAST('20110911 14:33:00' AS datetime) UNION ALL
SELECT 2, 'SomeData3', 'SomeData4', CAST('20110911 14:33:15' AS datetime) UNION ALL
SELECT 3, 'SomeData3', 'SomeData4', CAST('20110911 14:33:18' AS datetime) UNION ALL
SELECT 4, 'SomeData3', 'SomeData4', CAST('20110911 14:42:12' AS datetime) UNION ALL
SELECT 5, 'SomeData1', 'SomeData2', CAST('20110911 14:33:01' AS datetime) UNION ALL
SELECT 6, 'SomeData6', 'SomeData7', CAST('20110911 14:33:01' AS datetime) UNION ALL
SELECT 7, 'SomeData1', 'SomeData2', CAST('20110912 14:33:00' AS datetime) UNION ALL
SELECT 8, 'SomeData6', 'SomeData8', CAST('20110911 14:33:03' AS datetime)
),
ranked AS (
SELECT
*,
rn = ROW_NUMBER() OVER (PARTITION BY TextField1, TextField2 ORDER BY DateField1)
FROM sampledata
),
SELECT
r1.RecordID,
r1.TextField1,
r1.TextField2,
r1.DateField1
FROM ranked r1
INNER JOIN ranked r2 ON r1.TextField1 = r2.TextField1
AND r1.TextField2 = r2.TextField2
AND r1.rn = r2.rn - 1
WHERE r2.DateField1 BETWEEN r1.DateField1 AND DATEADD(SECOND, 30, r1.DateField1)
输出:
RecordID TextField1 TextField2 DateField1
----------- ---------- ---------- -----------------------
1 SomeData1 SomeData2 2011-09-11 14:33:00.000
2 SomeData3 SomeData4 2011-09-11 14:33:15.000