栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

查找列值连续增加的行

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

查找列值连续增加的行

无论如何,将它放在增加每张纸的行数方面

quoteid
是有帮助的(实际值在这里并不是真的有帮助)。 捕获 的天数(在此表中)是最简单的-
如果您想要其他内容(例如仅工作日,忽略周末/节假日等),则它会涉及更多;您可能需要一个日历文件。如果您还没有索引,您将要在[
stockid
createdate
]上建立索引。

WITH StockRow AS (SELECt stockId, closePrice, createdDate,   ROW_NUMBER() OVER(PARTITION BY stockIdORDER BY createdDate) rn       FROM Quote),     RunGroup AS (SELECt base.stockId, base.createdDate,   MAX(Restart.rn) OVER(PARTITION BY base.stockId  ORDER BY base.createdDate) groupingId       FROM StockRow base       LEFT JOIN StockRow Restart   ON Restart.stockId = base.stockId      AND Restart.rn = base.rn - 1      AND Restart.closePrice > base.closePrice)SELECt stockId,        COUNT(*) AS consecutiveCount,        MIN(createdDate) AS startDate, MAX(createdDate) AS endDateFROM RunGroupGROUP BY stockId, groupingIdHAVINg COUNT(*) >= 3ORDER BY stockId, startDate

从提供的数据中得出以下结果:

Increasing_RunstockId   consecutiveCount  startDate    endDate===================================================1         5      2012-01-01   2012-01-052         4      2012-01-01   2012-01-043         3      2012-01-02   2012-01-04

[SQL Fiddle Example](http://sqlfiddle.com/#!6/b1e78/4/0)

(提琴还有一个多次运行的示例)

该分析将忽略所有差距,正确匹配所有运行(下次开始运行正运行时)。


那么这是怎么回事?

StockRow AS (SELECt stockId, closePrice, createdDate,         ROW_NUMBER() OVER(PARTITION BY stockId      ORDER BY createdDate) rn  FROM Quote)

此CTE用于一个目的:我们需要一种方法来查找下一行/上一行,因此首先我们按(日期)的顺序对每一行进行编号…

RunGroup AS (SELECt base.stockId, base.createdDate,         MAX(Restart.rn) OVER(PARTITION BY base.stockId        ORDER BY base.createdDate) groupingId  FROM StockRow base  LEFT JOIN StockRow Restart         ON Restart.stockId = base.stockId AND Restart.rn = base.rn - 1     AND Restart.closePrice > base.closePrice)

…然后根据索引将它们加入。如果最后得到的是带有

LAG()
/的东西
LEAD()
,那么使用它们代替几乎可以肯定是一个更好的选择。不过,这里有一件关键的事情-
仅当行 不按顺序 (小于前一行)时才进行匹配。否则,该值最终会是
null
(使用
LAG()
,您需要使用类似
CASE
after
after的东西来实现此目的)。您得到一个看起来像这样的临时集:

B.rn   B.closePrice   B.createdDate  R.rn   R.closePrice   R.createdDate  groupingId1      15  2012-01-01     -      -   -   -2      13  2012-01-02     1      15  2012-01-01     13      17  2012-01-03     -      -   -   14      18  2012-01-04     -      -   -   15      10  2012-01-05     4      18  2012-01-04     4

…因此,

Restart
仅当上一个大于“当前”行时才有值。
MAX()
到目前为止,在窗口函数中使用的值已达到最大值……这
null
是最低值,它会导致所有其他行的行索引都保留下来,直到发生另一个不匹配(给出新值)为止。至此,我们基本上有了间隔和孤岛查询的中间结果,可以进行最终汇总了。

SELECt stockId,        COUNT(*) AS consecutiveCount,        MIN(createdDate) AS startDate, MAX(createdDate) AS endDateFROM RunGroupGROUP BY stockId, groupingIdHAVINg COUNT(*) >= 3ORDER BY stockId, startDate

查询的最后一部分是获取运行的开始日期和结束日期,并计算这些日期之间的条目数。如果日期计算有些复杂,则可能需要在此时进行。在

GROUPBY
被示出的几个合法实例中的一个 包括在列
SELECT
子句。该
HAVINg
子句用于消除“过短”的运行。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/634641.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号