给定一列生效日期,是否有SQL语句可以将其转换为日期范围?

给定一列生效日期,是否有SQL语句可以将其转换为日期范围?,sql,sqlite,range,Sql,Sqlite,Range,类似于我发布的另一个问题,给出下表 Promo EffectiveDate ------ ------------- PromoA 1/1/2016 PromoB 4/1/2016 PromoC 7/1/2016 PromoD 10/1/2016 PromoE 1/1/2017 将其转换为开始日期和结束日期的最简单方法是什么,如 Promo StartDate EndDate ------ --------- --------- PromoA 1/1/2016

类似于我发布的另一个问题,给出下表

Promo   EffectiveDate
------   -------------
PromoA  1/1/2016
PromoB  4/1/2016
PromoC  7/1/2016
PromoD  10/1/2016
PromoE  1/1/2017
将其转换为开始日期和结束日期的最简单方法是什么,如

Promo   StartDate  EndDate
------  ---------  ---------
PromoA  1/1/2016   4/1/2016
PromoB  4/1/2016   7/1/2016
PromoC  7/1/2016   10/1/2016
PromoD  10/1/2016  1/1/2017
PromoE  1/1/2017   null (ongoing until a new Effective Date is added)
更新 相关查询似乎是最简单的解决方案,但据我所知,它们效率极低,因为子查询必须在外部select的每行运行一次

我认为一个潜在的解决方案是,第二次从表中选择值,但消除第一个结果,然后将它们与第一个按顺序选择的索引(带有简单的左外连接)配对


例如,用字母代替上面的日期,第一个选择类似于A、B、C、D、E,第二个选择类似于B、C、D、E(这是第一个选择减去第一个记录“A”),然后通过顺序索引和简单的左外连接将它们配对,结果是A-B、B-C、C-D、D-E、E-null。但是,我无法找到使其工作的语法。

相关子查询可以查找所需的其他字段

SELECT
    yourTable.*,
    (
    SELECT MIN(lookup.EffectiveDate)
      FROM yourTable   AS lookup
     WHERE lookup.EffectiveDate > yourTable.EffectiveDate
    )
FROM
    yourTable
编辑

“每行必须运行一次”的概念是对SQL如何生成实际运行的执行计划的错误理解。将一个表连接到另一个表也是如此,连接必须每行至少运行一次。。。相关子查询的成本确实更高,但是使用适当的索引,它不会“非常高”,并且所描述的功能确实保证了这一点

如果您有另一个保证连续的字段,那么它将是微不足道的,但是不要尝试将现有的促销字段重新用于该附加目的

SELECT
    this.*,
    next.EffectiveEpoch
FROM
    yourTable    this
LEFT JOIN
    yourTable    next
        ON  next.sequential_id = this.sequential_id + 1

是的,您可以使用与
限制
相关的查询:

SELECT t.promo,t.effectiveDate as start_date,
       (SELECT s.effectiveDate FROM YourTable s
        WHERE s.date > t.date
        ORDER BY s.effectiveDate
        LIMIT 1) as end_date
FROM YourTable t
编辑:这里是一个带有连接的解决方案:

SELECT t.promo,t.effectiveDate as start_date,
       MIN(s.effectiveDate) as end_date
FROM YourTable t
LEFT JOIN YourTable s
 ON(t.date < s.date)
GROUP BY t.promo,t.effectiveDate
选择t.promo,t.effectiveDate作为开始日期,
最小值(s.effectiveDate)作为结束日期
从你的桌子上
左键加入你的桌子
日期(t日期
显示此项,使用子查询

select
p.promo,
p.EffectiveDate as "Start",
(select n.EffectiveDate from table_promo n where n.EffectiveDate > 
p.EffectiveDate order by n.EffectiveDate limit 1) as "End"
from table_promo p

我不遵守你的“where”条款。你找不到接线员了吗?看起来很有希望。但有一个问题。。。这看起来好像中间的限价很贵。难道不能用一个简单的MIN子句实现同样的事情吗?(即最小值(s.生效日期)其中s.effectiveDate>t.effectiveDate之类的东西?是的,但是没有保证这会比我建议的更快。这一点都不应该太贵@MarqueIV@MarqueIV在看到您的更新->否之后,相关查询不一定比
连接等备选方案慢。它们甚至可以更快有时。我将更新我的答案,并添加一个带有联接的解决方案。@MarqueIV这是正确的答案,或者至少是针对您的目标的正确查询样式。您的更新(您提到的“基本列表”在没有第一项的情况下联接到列表)这正是上面的连接查询所做的,但它的方式是针对基于集合的操作进行优化的。如果您搜索该术语,您将开始了解为什么这种思维方式对sql开发人员如此重要。相关子查询也可以工作。有时慢,有时快,这取决于您的情况,并且只取决于您对这两个选项都可以决定哪一个更有意义。@SlimsHost,关于这个答案中的第一个解决方案,我之前说过的“按/限制排序”似乎比简单的“按分钟排序”语句更昂贵,而“按分钟排序”语句的限制是由“分钟”的性质暗示的,不需要排序。你对此有何评论?我喜欢这个(您的代码是所有答案中最清晰的),但相关子查询不是效率很低,因为它们每行外部select都运行一次select吗?这真的是实现这一点的唯一方法吗?我已经添加了一个更新,更新了我认为应该采用的方法。介意对此进行评论吗?如果该解决方案不可行,那么将得到答案。如果可行,请将其放在回答(或更新此项)我将标记该项。实际上,他描述的功能不需要关联查询,可以通过连接完成(请参见我的答案)。这正是关联查询的确切目的,所以这是我想到的第一个解决方案。@sagi-将措辞从“需要”改为“保证”:是的,半笛卡尔乘积替代方案确实有效,但在更大的数据集上可能会受到影响。现在我100%同意:)