Oracle - 计算连续几天使用的相同值

Posted

技术标签:

【中文标题】Oracle - 计算连续几天使用的相同值【英文标题】:Oracle - Count the same value used on consecutive days 【发布时间】:2015-06-07 19:10:32 【问题描述】:
Date        jm       Text
--------    ----     ----
6/3/2015    ne       Good
6/4/2015    ne       Good
6/5/2015    ne       Same
6/8/2015    ne       Same

我想计算“相同”值在一组连续天中出现的频率。 我不想计算整个数据库的值。现在在当前日期是 2(上例)。

对我来说,永远不会出现“相同”非常重要......

查询必须忽略周末(6 月 6 日和 7 日)。

Date        jm       Text
--------    ----     ----
6/3/2015    ne       Same
6/4/2015    ne       Same
6/5/2015    ne       Good
6/8/2015    ne       Good

在本例中,计数为零

【问题讨论】:

您每天(周末除外)是否只有一个记录,或者某些日子可以有多个或没有?还有强制性的“你试过什么”? 如果6/9/2015 再次是“Ye”(或“Ya”)并且6/10/2015 是“ne”怎么办。您能否将它们添加到列表中,然后指定您想要的输出?我希望我不会惹恼你,但我真的很想弄清楚你到底想要什么。 最后是一个很好的例子:P 看看我的编辑... 【参考方案1】:

好的,我开始看图了,虽然一开始我以为你想用jm 来计数,现在看来你想用Text = 'Same' 来计数。无论如何,这就是这个查询应该做的。它获取当前日期的行。连接所有先前的行并计算它们。此外,它还显示当前文本(以及连接行的文本)是否。

所以查询会返回一行(如果今天有的话),会显示当前日期的日期、jm和Text,Text已经相同的连续天数(以防万一您想知道它是“好”的天数),以及文本“相同”的天数(0 或与其他计数相同)。

我希望这个查询是正确的,或者至少它让您了解如何使用CONNECT BY 解决问题。我应该提到我基于this question 的“星期五检测”。

另外,我手头没有 Oracle,所以请原谅我的任何小语法错误。

WITH
  VW_SAMESTATUSES AS
  ( SELECT      t.*  
    FROM        YourTable t
    START WITH  -- Start with the row for today
                t.Date = trunc(sysdate)
    CONNECT BY  -- Connect to previous row that have a lower date.
                -- Note that PRIOR refers to the prior record, which is
                -- actually the NEXT day. :)
                t.Date = PRIOR t.Date + 
                  CASE MOD(TO_CHAR(t.Date, 'J'), 7) + 1
                    WHEN 5 THEN 3 -- Friday, so add 3
                    ELSE 1 -- Other days, so add one
                  END
                -- And the Text also has to match to the one of the next day.
                AND t.Text = PRIOR t.Text)

SELECT    s.Date,
          s.jm,
          MAX(Text) AS CurrentText, -- Not really MAX, they are actually all the same
          COUNT(*) AS ConsecutiveDays,
          COUNT(CASE WHEN Text = 'Same' THEN 1 END) as SameCount
FROM      VW_SAMESTATUSES s
GROUP BY  s.Date,
          s.jm

【讨论】:

【参考方案2】:

此递归查询(可从 Oracle 版本 11g 获得)可能有用:

with s(tcode, tdate) as (
  select tcode, tdate from test where tdate = date '2015-06-08'
  union all 
  select t.tcode, t.tdate from test t, s 
    where s.tcode = t.tcode 
      and t.tdate = s.tdate - decode(s.tdate-trunc(s.tdate, 'iw'), 0, 3, 1) )
select count(1) cnt from s

SQLFiddle

我根据您的原始问题准备了示例数据,无需进一步编辑,您可以在附加的 SQLFiddle 中看到它们。 “文本”列的附加条件 非常简单,只需在where 子句中添加... and Text ='Same' 之类的内容即可。

在当前版本中,查询从给定日期开始计算前几天的数量(在第 2 行中更改),其中日期是连续的(不包​​括周末日),tcode 列中的值对于所有日期都是相同的。

部分:decode(s.tdate-trunc(s.tdate, 'iw'), 0, 3, 1) 用于减去天数,具体取决于是星期一还是其他日期,并且应该独立于 NLS 设置工作。

【讨论】:

以上是关于Oracle - 计算连续几天使用的相同值的主要内容,如果未能解决你的问题,请参考以下文章

sql 语句:一个字段,连续几天值大于0,获得天数

sql 语句:一个字段,连续几天值大于0,获得天数 怎么解决的?请教

Oracle中要查询出连续出现3天的数据

SQL:计算每个设备集连续出现相同值的所有记录并返回最高计数

sql 语句:一个字段,连续几天值大于0,获得天数 怎么解决的?请教

SQL:计算每个设备集连续出现相同值的所有记录并返回最高计数:百分比