SQL Query用于检索以秒为单位的记录

时间:2011-09-12 00:13:59

标签: sql sql-server

我正在尝试编写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=TextField1TextField2=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。

希望我能够清楚地解释清楚。任何帮助将不胜感激!

4 个答案:

答案 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)

这将返回您在示例中查找的两条记录。 t1t2之间的联接会返回符合条件的记录,然后加入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