比较两个时间戳的值,并根据 concat 函数中的预定义结构将它们插入结果中

Posted

技术标签:

【中文标题】比较两个时间戳的值,并根据 concat 函数中的预定义结构将它们插入结果中【英文标题】:Compare values of two timestamps and insert them into results based on a pre-defined structure within a concat function 【发布时间】:2020-09-23 13:57:09 【问题描述】:

DB-Fiddle:

CREATE TABLE operations (
    id int auto_increment primary key,
    time_stamp DATE,
    product VARCHAR(255),
    plan_week VARCHAR(255),
    quantity INT
);

INSERT INTO operations
(time_stamp, product, plan_week, quantity
)
VALUES 
("2020-01-01", "Product_A", "CW01", "125"),
("2020-01-01", "Product_B", "CW01", "300"),
("2020-01-01", "Product_C", "CW08", "700"),
("2020-01-01", "Product_D", "CW01", "900"),
("2020-01-01", "Product_G", "CW05", "600"),

("2020-03-15", "Product_A", "CW01", "570"),
("2020-03-15", "Product_C", "CW02", "150"),
("2020-03-15", "Product_E", "CW02", "325"),
("2020-03-15", "Product_G", "CW01", "482");

预期结果:

time_stamp     product     plan_week      quantity         plan_week_switch
2020-01-01     Product_A      CW01           125                  no
2020-03-15     Product_A      CW01           570                  no
2020-01-01     Product_B      CW01           300                  no
2020-01-01     Product_C      CW08           700              CW08-to-CW02
2020-03-15     Product_C      CW02           150              CW08-to-CW02
2020-01-01     Product_D      CW01           900                  no
2020-03-15     Product_E      CW02           325                  no
2020-01-01     Product_G      CW05           600              CW05-to-CW01
2020-03-15     Product_G      CW01           482              CW05-to-CW01

在上表中,我比较了两个timestamps 并检查plan_week 是否在两个timestamps 之间切换。 如果是,我希望在plan_week_switch 列中描述它从哪个plan_week 到哪个plan_week 已更改。

目前,我正在使用这个查询:

SELECT 
time_stamp,
product,
plan_week,
quantity,

 (CASE WHEN MIN(plan_week) over (PARTITION BY product) = MAX(plan_week) over (PARTITION BY product)
 THEN 'no' ELSE CONCAT(CAST(MIN(plan_week) over (PARTITION by product) AS CHAR), '-to-',
 MAX(plan_week) over (PARTITION BY product)) END) AS plan_week_switch

FROM operations
GROUP BY 1,2
ORDER BY 2,1;

问题是在Product_G 的情况下,此查询将CW01-to-CW05 而不是CW05-to-CW01 插入列plan_week_switch. 但是,我总是希望 年长者 timestamp 显示为第一周年轻 timestamp 周显示为第二周

我需要在查询中进行哪些更改才能实现此目的?

【问题讨论】:

不是有一个产品连续切换3次以上的情况吗? 没有。每个产品的每个时间戳都恰好分配了一周。因此,只能有两个开关。 那么Akina的回答就可以了。 【参考方案1】:
WITH cte AS ( SELECT time_stamp,
                     product,
                     plan_week,
                     quantity,
                     FIRST_VALUE(plan_week) OVER (PARTITION BY product ORDER BY time_stamp DESC) first_plan,
                     FIRST_VALUE(plan_week) OVER (PARTITION BY product ORDER BY time_stamp ASC) last_plan
              FROM operations )
SELECT time_stamp,
       product,
       plan_week,
       quantity,
       CASE WHEN first_plan = last_plan
            THEN 'no'
            ELSE CONCAT(first_plan, '-to-', last_plan) 
            END plan_week_switch
FROM cte;

fiddle

查询仍然为 Product_G 插入 CW01-to-CW05 而不是 CW05-to-CW01

使用后向窗口定义:

WITH cte AS ( SELECT time_stamp,
                     product,
                     plan_week,
                     quantity,
                     FIRST_VALUE(plan_week) OVER (PARTITION BY product ORDER BY time_stamp ASC) first_plan,
                     FIRST_VALUE(plan_week) OVER (PARTITION BY product ORDER BY time_stamp DESC) last_plan
              FROM operations )
SELECT time_stamp,
       product,
       plan_week,
       quantity,
       CASE WHEN first_plan = last_plan
            THEN 'no'
            ELSE CONCAT(first_plan, '-to-', last_plan) 
            END plan_week_switch
FROM cte;

fiddle

【讨论】:

查询仍然为 Product_G 插入 CW01-to-CW05 而不是 CW05-to-CW01 @Michi 在窗口定义中交换 ASC 和 DESC 如果顺序错误。 仅用于我自己的文档:dbfiddle.uk/… 也用于我自己的文档:dbfiddle.uk/…

以上是关于比较两个时间戳的值,并根据 concat 函数中的预定义结构将它们插入结果中的主要内容,如果未能解决你的问题,请参考以下文章

前端学数据库之函数

PHP用strtotime()函数比较两个时间的大小实例详解

比较C中两个文件的日期和时间[关闭]

在Oracle中怎样连接两个字段

没有时间戳的 HQL 中的日期比较

如何根据时间戳匹配值,当时间戳不存在时,该值是前一个时间戳的值