SQL - 查询比较同一查询中多行的列

3

我将尝试分析查询中的唯一模式,并显示该模式是否出现在另一列中。

例如:

从我的查询结果中,我得到:

----------
| Date | Value|
----------
|  1   |  0.8 |
----------
|  2   |  0.2 |
----------
|  3   |  0.4 |
----------
|  4   |  0.6 |
----------
|  5   |  0.3 |

我想检查是否有3个点是升序/降序的,并得到以下结果:
----------
| Date | Value| Ascending |
----------
|  1   |  0.8 |     0     |
----------
|  2   |  0.2 |     1     |
----------
|  3   |  0.4 |     1     |
----------
|  4   |  0.6 |     1     |
----------
|  5   |  0.3 |     0     |

升序列只是一个位,所有形成该模式的值都变为true。 有什么想法吗?

这将是Oracle中的LAG函数。 - Randy
1
为什么记录“4”被标记为“Ascending = 1”? - Gordon Linoff
在这种情况下形成升序模式的序列是0.2、0.4、0.6。实际上,我正在尝试寻找长度为5的升序序列,但为了简化问题,我只放了3个数字。 - user2755428
1个回答

8
以下代码并不是完整的答案。它只是比较两个数,一个与下一个。
你需要与下一个值进行比较。假设“日期”列真正是数值型的,而且没有空缺(正如你在问题中所建议的),那么以下内容应该适用于两种数据库:
select t.*,
       (case when tnext.value > t.value then 1 else 0 end) as "ascending"
from t left outer join
     t tnext
     on t."date" = tnext."date" - 1;

如果你想比较3行,需要更多的解释。我无法想到任何定义适用于你的结果。
编辑:
嗯,你似乎想找到升序序列,并标记至少有三行的序列。如果是这样,这就有点难了。以下使用以下技术枚举序列。它识别序列的开始,然后计算每个值的开始数量。
要识别升序序列的开始,请查找值下降的对:
select t.*,
       (select 1
        from t tprev
        where tprev."date" = t."date" - 1 and
              tprev.value >= t.value
      ) as IsAscStart
from t;

为每个序列分配独特的ID:
select t.*
       (select count(*)
        from t t1 join
             t tprev
             on tprev."date" = t1."date" - 1 and
                tprev.value > t1.value
        where t1."date" <= t."date"
       ) as AscGrouping
from t;

从这个点开始的挑战是获取序列的长度。在SQL Server和MySQL之间,做法差异很大,我想不到一种简单的与数据库无关的方法来实现。

第二次编辑:

在SQL Server中,您可以按以下方式实现所需操作:

with cte as (
    select t.*
           (select count(*)
            from t t1 join
                 t tprev
                 on tprev."date" = t1."date" - 1 and
                    tprev.value > t1.value
            where t1."date" <= t."date"
           ) as AscGrouping
    from t
   )
select t."date", t.value,
       (case when seqlen >= 3 then 1 else 0 end) as "Ascending"
from (select cte.*, count(*) over (partition by AscGrouping) as seqlen
      from cte
     ) t

这是一个不错的代码。但是对于 date = 4,它返回了 0,而不是 OP 所期望的输出 1 - peterm
你有没有想过如何在SQL Server中改变序列的长度? - user2755428
谢谢你的帮助,Gordon。有一件事让我困惑,当你说“t1.id <= t.id”时,你指的是哪一列?因为没有“id”列。 - user2755428
@user2755428...我是指日期列。 - Gordon Linoff
这个解决方案很棒。仅供其他可能查看此解决方案的人们注意,我想你可能是想写成“tprev.value > t1.value”,而不是“tprev.value > t.value”,对吗? - user2755428

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接