【问题标题】:List all SQL records occurring within x hours of another set of records列出在另一组记录的 x 小时内出现的所有 SQL 记录
【发布时间】:2013-02-28 20:12:15
【问题描述】:

我什至接近这个了吗?
我正在尝试列出所有包含“Ape”的记录......以及所有 在任何“Ape”记录之前 x 天出现的记录。 我想我需要一个自联接表?

-- Doesn't work:
SELECT tblA.MyDate, tblA.MyPet  FROM TestTable As tblA                      WHERE tblA.MyPet='Ape'
UNION
SELECT tblA.MyDate, tblA.MyPet  FROM TestTable AS tblA, TestTable AS tblB   WHERE tblA.MyPet='Ape' AND tblA.MyDate>tblB.MyDate-0.5 AND tblA.MyDate<tblB.MyDate
ORDER BY tblA.MyDate ASC

-- Doesn't work:
SELECT * FROM TestTable As tblA     INNER JOIN TestTable As tblB ON tblA.MyPet =         'Ape'     AND tblA.MyDate>tblB.MyDate-1  AND tblA.MyKey>tblB.MyKey

-- Doesn't work:
SELECT * FROM TestTable WHERE MyDate IN (SELECT MyDate-1 FROM TestTable WHERE MyPet='Ape')

-- Doesn't work
SELECT id, uid, date FROM orders current
WHERE EXISTS 
(
   SELECT * from orders future 
   WHERE future.date < DateAdd(DAYS, 1, current.date)
   AND future.date > getdate()
   AND future.uid = current.uid
)

-- Doesn't work
SELECT * FROM TestTable AS tblA
WHERE EXISTS
( 
   SELECT * FROM TestTable AS tblB
   WHERE tblB < DateAdd(DAYS, 1, tblA.MyDate)
   AND tblB.MYDate > GetDate()
   AND tblA.MyKey = tblB.MyKey
)

=========================== 下面是表格:

CREATE TABLE TestTable   
(
MyKey       Int             IDENTITY(1,1)   PRIMARY KEY,     

MyDate      DateTime        NOT NULL    DEFAULT GetDate(),
MyPet       VarChar(22)     NOT NULL    DEFAULT ''
)

INSERT INTO TestTable(MyDate, MyPet)   VALUES('01-Dec-2012 06:12:10', 'Cat'   )
INSERT INTO TestTable(MyDate, MyPet)   VALUES('01-Dec-2012 10:11:10', 'Dog'   )
INSERT INTO TestTable(MyDate, MyPet)   VALUES('01-Dec-2012 14:13:10', 'Fish'  )
INSERT INTO TestTable(MyDate, MyPet)   VALUES('01-Dec-2012 16:14:10', 'Duck'  )
INSERT INTO TestTable(MyDate, MyPet)   VALUES('01-Dec-2012 17:15:10', 'Bird'  )
INSERT INTO TestTable(MyDate, MyPet)   VALUES('01-Dec-2012 20:16:10', 'Kitten')
INSERT INTO TestTable(MyDate, MyPet)   VALUES('02-Dec-2012 01:17:10', 'Dog'   )
INSERT INTO TestTable(MyDate, MyPet)   VALUES('02-Dec-2012 12:19:10', 'Fish'  )
INSERT INTO TestTable(MyDate, MyPet)   VALUES('02-Dec-2012 13:20:10', 'Duck'  )
INSERT INTO TestTable(MyDate, MyPet)   VALUES('02-Dec-2012 14:21:10', 'Bird'  )
INSERT INTO TestTable(MyDate, MyPet)   VALUES('02-Dec-2012 16:18:10', 'Cat'   )     -- These are within 1 day before any "Ape" record

INSERT INTO TestTable(MyDate, MyPet)   VALUES('03-Dec-2012 05:26:10', 'Dog'   )     --
INSERT INTO TestTable(MyDate, MyPet)   VALUES('03-Dec-2012 11:22:10', 'Kitten')     --
INSERT INTO TestTable(MyDate, MyPet)   VALUES('03-Dec-2012 12:23:10', 'Duck'  )     --
INSERT INTO TestTable(MyDate, MyPet)   VALUES('03-Dec-2012 13:24:10', 'Bird'  )     --
INSERT INTO TestTable(MyDate, MyPet)   VALUES('03-Dec-2012 14:25:10', 'Ape'   )     -- An "Ape" record
INSERT INTO TestTable(MyDate, MyPet)   VALUES('03-Dec-2012 16:27:10', 'Cat'   )
INSERT INTO TestTable(MyDate, MyPet)   VALUES('04-Dec-2012 01:32:10', 'Dog'   )
INSERT INTO TestTable(MyDate, MyPet)   VALUES('04-Dec-2012 04:28:10', 'Fish'  )
INSERT INTO TestTable(MyDate, MyPet)   VALUES('04-Dec-2012 07:30:10', 'Bird'  )
INSERT INTO TestTable(MyDate, MyPet)   VALUES('04-Dec-2012 10:31:10', 'Kitten')
INSERT INTO TestTable(MyDate, MyPet)   VALUES('04-Dec-2012 16:29:10', 'Duck'  )
INSERT INTO TestTable(MyDate, MyPet)   VALUES('05-Dec-2012 11:35:10', 'Kitten')
INSERT INTO TestTable(MyDate, MyPet)   VALUES('05-Dec-2012 12:36:10', 'Duck'  )
INSERT INTO TestTable(MyDate, MyPet)   VALUES('05-Dec-2012 13:33:10', 'Duck'  )
INSERT INTO TestTable(MyDate, MyPet)   VALUES('05-Dec-2012 13:37:10', 'Bird'  )
INSERT INTO TestTable(MyDate, MyPet)   VALUES('05-Dec-2012 14:34:10', 'Dog'   )
INSERT INTO TestTable(MyDate, MyPet)   VALUES('06-Dec-2012 04:41:10', 'Fish'  )     -- These are within 1 day before any "Ape" record
INSERT INTO TestTable(MyDate, MyPet)   VALUES('06-Dec-2012 05:39:10', 'Dog'   )     --
INSERT INTO TestTable(MyDate, MyPet)   VALUES('06-Dec-2012 14:38:10', 'Kitten')     --
INSERT INTO TestTable(MyDate, MyPet)   VALUES('06-Dec-2012 16:40:10', 'Ape'   )     -- An "Ape" record
INSERT INTO TestTable(MyDate, MyPet)   VALUES('06-Dec-2012 16:42:10', 'Duck'  )

【问题讨论】:

    标签: sql sql-server select nested-sets self-join


    【解决方案1】:

    这就是你想要的:

    SELECT DISTINCT
        tblA.*
    FROM TestTable AS tblA
        INNER JOIN TestTable AS tblB
            ON (tblA.MyDate >= DATEADD(day, -1, tblB.MyDate)) AND (tblA.MyDate <= tblB.Mydate) AND (tblB.MyPet = 'Ape');
    

    这是有效的SQLFiddle

    更新

    根据下面 Gordon 的评论添加了 DISTINCT

    【讨论】:

    • 。 .我对此表示赞同,但准确地说,应该是select distinct tblA.*,因为当多个记录匹配时,您会得到重复。您不需要outer join(您没有),因为原始记录将始终匹配。
    • @GordonLinoff 我将用DISTINCT 更新答案。谢谢!
    【解决方案2】:

    我认为您正在寻找的公式是:

    SELECT *
    FROM TestTable tblA
    WHERE EXISTS (SELECT *
                  FROM TestTable tblB
                  WHERE tblB.mydate between tblA.MyDate - X and tblA.MyDate and
                        tblB.MyPet = 'Ape'
                 )
    

    两个音符。首先,这使用语法“date - x”,当日期为datetime 而不是date 时有效。相当于dateadd(day, -x, tbla.MyDate)

    其次,这将返回所有带有 'Ape' 的记录,因为 between 处理相等性。

    Jesse 的查询使用外连接和 distinct 执行基本相同的操作。

    【讨论】:

      【解决方案3】:
      1. 处理:分别编写查询的每一半并测试它是否有效。然后用 UNION 将它们放在一起。
      2. 如果要删除重复项,请使用 UNION ALL 而不是 UNION。

      【讨论】:

      • 我不知道如何“写两半”。 (“那就用 UNION 加入他们吧”是最简单的部分。)
      【解决方案4】:

      SQL Fiddle

      查询 1

      -- Doesn't work:
      SELECT tblA.MyDate, tblA.MyPet  
      FROM TestTable As tblA
      WHERE tblA.MyPet='Ape'
      UNION all
      SELECT tblA.MyDate, tblA.MyPet  
      FROM TestTable AS tblA
      WHERE dateadd(day, 1, tblA.MyDate) < (select min(MyDate) from TestTable where MyPet = 'Ape')
      ORDER BY tblA.MyDate ASC
      

      Results

      |                          MYDATE |  MYPET |
      --------------------------------------------
      | December, 01 2012 06:12:10+0000 |    Cat |
      | December, 01 2012 10:11:10+0000 |    Dog |
      | December, 01 2012 14:13:10+0000 |   Fish |
      | December, 01 2012 16:14:10+0000 |   Duck |
      | December, 01 2012 17:15:10+0000 |   Bird |
      | December, 01 2012 20:16:10+0000 | Kitten |
      | December, 02 2012 01:17:10+0000 |    Dog |
      | December, 02 2012 12:19:10+0000 |   Fish |
      | December, 02 2012 13:20:10+0000 |   Duck |
      | December, 02 2012 14:21:10+0000 |   Bird |
      | December, 03 2012 14:25:10+0000 |    Ape |
      | December, 06 2012 16:40:10+0000 |    Ape |
      

      编辑

      如果您需要记录发生在第一个 Ape 记录之前 x 天 那么查询应该是(例如 x = 1)

      SELECT tblA.MyDate, tblA.MyPet  
      FROM TestTable As tblA
      WHERE tblA.MyPet='Ape'
      UNION
      SELECT tblA.MyDate, tblA.MyPet  
      FROM TestTable AS tblA
      WHERE (select min(MyDate) from TestTable where MyPet = 'Ape') between tblA.MyDate and dateadd(day, 1, tblA.MyDate)
      ORDER BY tblA.MyDate ASC
      

      【讨论】:

      • 该代码+结果列出的记录早于...任何“猿”记录前 1 天。 (我看到了 12 月 3 日的 APE……然后是 12 月 1 日的记录。)
      猜你喜欢
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多