0

假设我有一个包含四列的表:ID、ParentID、Timestamp、Value。ParentID 改变了值的含义。我需要返回该表中的所有条目,其中它们的 ParentID = 1 并且它们的时间戳在表中 ParentID = 2 的项目的时间戳和 ParentID.Value > 10 的项目的时间戳内。

例如,这里有一些数据:

ID    ParentID    TimeStamp    Value
1     1           51           1
2     2           52           11
3     1           53           2
4     1           54           3
5     2           55           9
6     1           56           4
7     2           57           12
8     1           58           5
9     1           53.5         1

我需要一个查询来返回那些 ID 为 3、4、8 和 9 的行。这个查询在 SQL 或 LINQ 中会是什么样子?是否允许自己加入,你会在这里使用这种方法吗?我坚持如何确定时间戳范围。我正在使用 Sqlite。谢谢。

澄清:我想通过 ParentID = 2 的最新(按时间戳判断)行进行过滤。

4

3 回答 3

3

这个丑陋而缓慢的查询为每个 ParentID = 1 行找到足够的 ParentID = 2 行,并检查 Value 是否大于 10;如果是,则输出行:

select * 
  from table1
 where table1.parentid = 1
   and exists
       (
         select null
         -- Isolate previous ParentID = 2 row
         from
         (
           select p2.value
             from table1 p2
            where p2.timestamp < table1.timestamp
              and p2.parentid = 2
              -- Only one needed
            order by p2.timestamp desc
            limit 1
         ) p2_1
         -- Make sure it has appropriate value
         where p2_1.value > 10
       )

这值得在架构更改后更新表的上下文中运行一次。如果您可以将 ParentID 更改为真正的 ParentID(即,分层连接记录)查询将变得微不足道:

select Child.*
  from table1 Child
 inner join table1 Parent
    on child.ParentID = Parent.ID
 where Parent.Value > 10

当然,必须在插入之前找到 ParentID,如果业务模型允许乱序插入,则会涉及一些数学问题。如果您所期望的只是简单地附加时间戳,这将是最简单的解决方案。

此查询有Sql Fiddle现场测试。

于 2012-05-07T23:51:04.480 回答
0

这是一个不寻常的问题。如果这是家庭作业,你应该这样标记它。

以下查询似乎符合您的描述:

select p1.*
from (select *
      from table t
      where ParentId = 1
     ) p1 cross join
     (select min(TimeStamp) as minTS, max(TimeStamp) as maxTS
      from table t
      where ParentId = 2 and value > 10
     ) p2
where t.TimeStamp between minTS and maxTS   

您的问题的答案是“是”,所有 SQL 数据库都支持自联接。

于 2012-05-07T20:21:38.787 回答
0

使用 LINQ,如果它不必是一个查询,这应该可以工作:

var values = table.Where(a => a.parentid == 2 
                           && a.value > 10)
                  .Select(a.timestamp);

var min = values.Min();
var max = values.Max(); 

var result = table.Where(a => a.parentid == 1
                            && timestamp >= min 
                            && timestamp <= max)
                  .Select(a => a.value);
于 2012-05-07T20:55:52.727 回答