选择价格没有变化的行

Posted

技术标签:

【中文标题】选择价格没有变化的行【英文标题】:Select rows where price didn't change 【发布时间】:2011-01-19 17:33:04 【问题描述】:

假设您有一个类似的表(我使用的是 SQL Server 2008,没有审核日志 - 表很大):

 SecID | Date    | Price
 1       1/1/11      10
 1       1/2/11      10
 1       1/3/11      5
 1       1/4/11      10
 1       1/5/11      10

假设这个表是巨大的(不同的 secID 和日期有数百万行)- 我想在价格变化时返回记录(寻找比使用游标和迭代更好的东西):

我想知道如何获得:

 SecID | StartDate | EndDate | Price
 1        1/1/11      1/2/11    10
 1        1/3/11      1/3/11    5
 1        1/4/11      1/5/11    10

即另一种看待它的方式是,我正在寻找价格保持不变的日期范围。

【问题讨论】:

您是否将此信息存储在另一个表中(即审核日志)? 不清楚你想要什么——它是一组记录指定价格保持不变的日期范围吗? @Larry,是的,正是我要找的东西 如果价格发生变化,然后又改回您日期范围内的原始值怎么办?你想包含它吗? @Matthew - 是的。 (参见示例结果,其中 10 显示了两次) 【参考方案1】:

这是一个“孤岛”问题。

declare @Yourtable table
 (SecID int, Date Date, Price int)

 INSERT INTO @Yourtable
SELECT 1,GETDATE()-5,10 union all
SELECT 1,GETDATE()-4,10 union all
SELECT 1,GETDATE()-3,5 union all
SELECT 1,GETDATE()-2,10 union all
SELECT 1,GETDATE()-1, 10

;WITH cte AS
(
SELECT SecID,Date,Price,
       ROW_NUMBER() OVER (PARTITION BY SecID ORDER BY Date) -
       ROW_NUMBER() OVER (PARTITION BY Price, SecID ORDER BY Date) AS Grp
FROM @Yourtable
)
SELECT SecID,Price, MIN(Date) StartDate, MAX(Date) EndDate
FROM cte
GROUP BY SecID, Grp, Price
ORDER BY SecID,  MIN(Date)

【讨论】:

其实这个答案比我的好:) 顺便说一句,什么是“孤岛”问题? @Denis - 在您的问题中查找连续的数据“岛”。我的答案中的解决方案基于我最初在 Itzik Ben Gan 的一本书中读到的方法。【参考方案2】:

如果值不变,则标准偏差为零

select secId
  from ...
 group by secId
having count(*) = 1  
    OR stdev(price) = 0

【讨论】:

@Matthew,除了必须读取每一行之外,我无法想象它会增加多少,因为磁盘读取会淹没任何正在进行的内存操作。【参考方案3】:

我认为这应该可行

SELECT SecID, Min(Date) AS StartDate, Max(Date) AS EndDate, Price FROM BigTable GROUP BY SecID, EndDate Having Min(Date) != MAx(Date) And Date != NULL

【讨论】:

这不起作用,因为在我的示例的第 2 行 Min(Date) = Max(Date) 并且最后一行将被删除(因为 price = 10 已经在第一行中找到)。不过很好的尝试-考虑了一段时间。 (顺便说一句,日期被标记为“NOT NULL”) 您还应该按价格分组,而不是按结束日期分组。无论如何,如果你替换它,并取出HAVING,它应该可以正常工作 这也行不通,因为如果您按 SecID、Price 分组,那么您的结果集中将有 (1, 10) 和 (1, 5) 所以 2 行。你应该有 3: (1, 10), (1, 5) 和 (1,10)。 是的,抱歉,已经有一段时间了 :)

以上是关于选择价格没有变化的行的主要内容,如果未能解决你的问题,请参考以下文章

用 WooCommerce 3 中选择的变化价格替换可变价格范围

选择值发生变化的行

如何从特定小时范围内的行中选择最小值?

比较数据表并返回有变化的行

已解决 - ReactJS - 父表上的行选择崩溃嵌套表

NOT IN 子句中缺少数据行