【问题标题】:Filtering SQL query by row and by date range按行和日期范围过滤 SQL 查询
【发布时间】:2011-05-25 15:00:06
【问题描述】:

我有一个时间索引的 Oracle 数据库,我正在尝试按日期范围进行查询。我还想在查询中减少数据,以免数据过多。

独立日期查询(0.203s 2352 行):

select oracle_time from t_ssv_soh_packets0
where oracle_time >= TIMESTAMP '2009-01-01 00:00:00' 
AND oracle_time <= TIMESTAMP '2009-01-31 00:00:00' 

支持减少查询(0.89 秒内 1017 个):

select oracle_time from t_ssv_soh_packets0
where (rowid,0) in (select rowid, mod(rownum,50) from t_ssv_soh_packets0)

当我尝试将它们组合起来时,它需要很长时间(32.547 秒内 48 行):

select oracle_time from t_ssv_soh_packets0
where oracle_time >= TIMESTAMP '2009-01-01 00:00:00' 
AND oracle_time <= TIMESTAMP '2009-01-31 00:00:00' 
AND (rowid,0) in (select rowid, mod(rownum,50) from t_ssv_soh_packets0)

显然,我在这里做的事情根本上是错误的,但我不知道如何同时按日期查询和减少数据。

【问题讨论】:

    标签: sql oracle date reduce


    【解决方案1】:

    您正在根据不在您选择的日期范围内的行评估您的缩减逻辑。

    将缩减逻辑应用于包含您的日期范围的子查询。

    稍后: 这就是我的意思。

    select oracle_time from (
      select oracle_time, rownum as limited_row_num
      from t_ssv_soh_packets0 
      where oracle_time >= TIMESTAMP '2009-01-01 00:00:00'  
      AND oracle_time <= TIMESTAMP '2009-01-31 00:00:00'  
    ) as time_range
    where mod(limited_row_num,50) =  0
    

    【讨论】:

    • 您的查询在 Oracle 中不起作用,这是我一直使用的数据库。我不知道如何将它翻译成 Oracle 喜欢的子查询。我认为'group by'子句是最兼容跨数据库的。
    • 对不起。谢谢你告诉我。
    【解决方案2】:

    摆脱in

    为什么要使用这个?:

    select oracle_time from t_ssv_soh_packets0
    where (rowid,0) in (select rowid, mod(rownum,50) from t_ssv_soh_packets0)
    

    你唯一的条件是 mod(rownum, 50)

    select * from t where mod(rownum, 50)=0
    

    最后一行应该是AND mod(rownnum,50)=0 而不是in 的自联接。

    【讨论】:

    • 在我的示例中,我错误地将表名 't_ssv_soh_packets0' 更改为 'table'。我正在尝试获取所有存储在“t_ssv_soh_packets0”中的数据。您的查询不起作用,Oracle 似乎认为问题出在连接行上,特别是“作为数据包”。我收到“缺少关键字”错误。
    • Oracle 并不总是支持“as”,因为它不是 ANSI 投诉的。如果您在帖子中使用 Oracle,那很好。
    • 此查询:select oracle_time from t_ssv_soh_packets0 where mod(rownum, 50)=0 选择 0 行。
    • 我认为像 select t1.oracle_time from t_ssv_soh_packets0 t1 left join t_ssv_soh_packets0 t2 on mod(rownum, 100)=0 这样的东西会起作用,但它表现得好像模组根本不存在。
    【解决方案3】:

    您还可以通过应用SAMPLE() 子句让 Oracle 从结果中选择一个随机样本:

    选择 oracle_time 从 t_ssv_soh_packets0 在哪里 ... 样品(50)

    将随机返回 50% 的行

    【讨论】:

    • 您的评论已被截断。我得到了以下工作:SELECT oracle_time FROM t_ssv_soh_packets0 SAMPLE(50) WHERE oracle_time &gt;= TIMESTAMP '2009-01-01 00:00:00' AND oracle_time &lt;= TIMESTAMP '2009-01-31 00:00:00' 这在 0.1 秒内返回了 1182 行。
    • 奇怪,我编辑了我的代码示例。出于某种原因,SO 不喜欢 WHERE 和 SAMPLE()
    【解决方案4】:

    感谢 'Narveson' 和 'nate c' 的指点,我终于弄明白了。这是我提出的(可能是 Oracle 特定的)查询:

    select oracle_time from t_ssv_soh_packets0 where oracle_time &gt;= TIMESTAMP '2009-01-01 00:00:00' AND oracle_time &lt;= TIMESTAMP '2009-01-31 00:00:00' group by oracle_time, rownum having mod(rownum, 50)=0

    此查询在 0.031 秒内返回 47 行。原来的时间查询有 2352 行,这是有道理的。

    ORAFAQ 帮助我找到了最终解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-07
      • 1970-01-01
      相关资源
      最近更新 更多