比较两个时间戳的值,并根据 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 函数中的预定义结构将它们插入结果中的主要内容,如果未能解决你的问题,请参考以下文章