比较两个时间戳的值并将它们放在结果的两列中

Compare values of two timestamps and put them in two columns in results

DB-Fiddle

CREATE TABLE operations (
    id SERIAL PRIMARY KEY,
    time_stamp DATE,
    product VARCHAR,
    plan_week VARCHAR,
    quantity DECIMAL
);

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-01-01', 'Product_J', 'CW01', '465'),

('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'),
('2020-03-15', 'Product_J', 'CW12', '323');

预期结果:

time_stamp  |    product  |   plan_week  |  quantity  |  first_plan  |  last_plan  |
----------  |-------------|--------------|------------|--------------|-------------|---
2020-01-01  |  Product_A  |      CW01    |     125    |     CW01     |     CW01    |
2020-03-15  |  Product_A  |      CW01    |     570    |     CW01     |     CW01    |
------------|-------------|--------------|------------|--------------|-------------|---            
2020-01-01  |  Product_B  |      CW01    |     300    |     CW01     |     CW01    |
------------|-------------|--------------|------------|--------------|-------------|---    
2020-01-01  |  Product_C  |      CW08    |     700    |     CW08     |     CW02    |
2020-03-15  |  Product_C  |      CW02    |     150    |     CW08     |     CW02    |
------------|-------------|--------------|------------|--------------|-------------|---    
2020-01-01  |  Product_D  |      CW01    |     900    |     CW01     |     CW01    |
------------|-------------|--------------|------------|--------------|-------------|---    
2020-03-15  |  Product_E  |      CW02    |     325    |     CW02     |     CW02    |
------------|-------------|--------------|------------|--------------|-------------|---  
2020-01-01  |  Product_G  |      CW05    |     600    |     CW05     |     CW01    |
2020-03-15  |  Product_G  |      CW01    |     482    |     CW05     |     CW01    |
------------|-------------|--------------|------------|--------------|-------------|---   
2020-01-01  |  Product_J  |      CW01    |     465    |     CW01     |     CW12    |
2020-03-15  |  Product_J  |      CW12    |     323    |     CW01     |     CW12    |

我想比较每个 product 的两个 timestampsplan_week,并将它们排列在彼此下方,正如您在预期结果中看到的那样。

first_plan 列中,我想列出第一个时间戳的周数。
last_plan 列中,我想列出最后一个 teimestamp 的星期。

我目前正在使用此查询来获得 postgresSQL 中的结果:

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;

但是,当我将此 sql 应用于 amazon-redshift 时,我得到:

ERROR: Aggregate window functions with an ORDER BY clause require a frame clause

我需要如何修改查询才能使其在 redshift 中也能正常工作?

手册解释了什么是框架条款:

(window 应该向前或向后看多少行。)


您可能想要类似...

SELECT 
  time_stamp,
  product,
  plan_week,
  quantity,
  FIRST_VALUE(plan_week)
    OVER (
      PARTITION BY product
          ORDER BY time_stamp
      ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
    )
      AS first_plan,
  LAST_VALUE(plan_week)
    OVER (
      PARTITION BY product
          ORDER BY time_stamp
      ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
    )
      AS last_plan
FROM
  operations

注意,我使用 LAST_VALUE() 而不是反转 ORDER BY。通常,最好为多个 window 函数保留相同的 window 子句。它使优化者的生活更轻松,这对您有好处。