我有一个名为products的表,其中包含以下模式:

CREATE TABLE products (
  id INT PRIMARY KEY,
  sku TEXT NOT NULL,
  fee REAL
);

以及另一个包含费用更改日志(log)的表,其中包含此模式:

CREATE TABLE fee_change(
  id SERIAL PRIMARY KEY,
  sku_id INT NOT NULL,
  old_fee REAL NOT NULL,
  new_fee REAL NOT NULL,
  FOREIGN KEY (sku_id) REFERENCES products(id)
);

是否要在一个sql中获取每个sku的最后两次费用更改,而不是每个sku的两行,我希望有两个新列,分别包含旧的费用1、新的费用1、旧的费用2、新的费用2:

预期结果:

   id   |    sku   |   old_fee_1  |  new_fee_1  |  old_fee_2  |  new_fee_2
    1   |    ASC   |      4       |     2.5     |      3      |      4
    2   |    CF2   |      4       |      1      |      3      |      4
    3   |    RTG   |     0.5      |      1      |      2      |     0.5
    4   |    VHN5  |     null     |     null    |     null    |     null

dbfiddle

推荐答案

作为起点,我从你链接的fiddle上回答了你的问题:

SELECT *
FROM products AS p
LEFT JOIN LATERAL (
    SELECT *
    FROM fee_change
    WHERE sku_id = p.id
    ORDER BY id DESC
    LIMIT 2
) AS oo
ON true

demo: db<>fiddle

您可以使用FILTER子句(也可以与CASE WHEN构造一起使用)来透视联接表.要获取轴值,可以添加行计数(使用row_number()窗口函数):

SELECT 
    p.id, p.sku, p.fee,
    MAX(old_fee) FILTER (WHERE row_number = 1) AS old_fee_1,       -- 2
    MAX(new_fee) FILTER (WHERE row_number = 1) AS new_fee_1,
    MAX(old_fee) FILTER (WHERE row_number = 2) AS old_fee_2,
    MAX(new_fee) FILTER (WHERE row_number = 2) AS new_fee_2
    
FROM products AS p
LEFT JOIN LATERAL (
    SELECT 
        *,
        row_number() OVER (PARTITION BY sku_id)                    -- 1
    FROM fee_change
    WHERE sku_id = p.id
    ORDER BY id DESC
    LIMIT 2
) AS oo ON true

GROUP BY p.id, p.sku, p.fee                                        -- 2
  1. 创造pivot值
  2. 执行筛选聚合(aggregation)以创建数据透视(pivoted)表.

Sql相关问答推荐

无效和不匹配的计数

用于过滤嵌套对象或数组中的JSON数据的WHERE条件

对表进行多项 Select 以返回最大值和时间

无法将发票与产品价格相关联

按两列分组,并根据SQL中的条件返回第三个列值

在SQL查询中查找客户端的最短日期比较列和多行

如何使用SQL生成数据的滚动3天总和

从重复值中获取最新值

在 Oracle 21c 中透视文本值

PostgreSQL-用第一个非空填充以前的值

JSON对象查询SQL服务器

使用SQLAlchemy和Postgres数据库创建新行时,为什么我的创建日期比更新日期晚?

如何在 DAX 中通过 Window 函数应用订单

在 postgresql 中,我可以将其组合成一个查询吗?

从每行中排除最大元素

包含多行的 SQL 查询

使用 JSON_BUILD_OBJ 从 Postgres 返回 JSON

snowflake插入覆盖行为

为什么这是 AND,OR with NULL 的真值表?

从 Pyspark 转换为具有多个分组条件的语句时的情况