SQL - 选择一个比较同一查询的多行的列

时间:2013-09-06 19:31:58

标签: sql sql-server

我正在尝试从查询中分析独特的模式,并显示模式是否出现在另一列中。

例如

从我的查询中得到:

----------
| 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     |

升序列只是一点点,形成该模式的所有值都变为真。

有什么想法吗?

1 个答案:

答案 0 :(得分: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行,则需要更多解释。没有我能想到的定义适用于您的结果。

编辑:

嗯,你似乎想要找到升序,并标记至少有三行的序列。如果是这样,这有点困难。以下使用以下技术列举序列。它标识序列的开头,然后计算每个值的起始数。

要识别升序序列的开头,请查找值 down 的对:

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之间的方法差异很大,所以我想不出一种简单的,与数据库无关的方法。

编辑II:

在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
相关问题