gpt4 book ai didi

postgresql - 在具有复合键(多列)的查询上使用交叉表

转载 作者:行者123 更新时间:2023-11-29 11:51:30 25 4
gpt4 key购买 nike

我最近从 SQL Server 切换到 PostgreSQL 并试图找到等效的数据透视函数。我无法使用可以使用 SQL Server 实现的交叉表获得所需的输出。

示例数据。

CREATE TABLE loc
AS
SELECT location, sub_location, step, amount
FROM ( VALUES
( 100 , '100_A', 'step_1', 2 ),
( 100 , '100_A', 'step_2', 7 ),
( 100 , '100_A', 'step_3', 6 ),
( 100 , '100_B', 'step_1', 5 ),
( 100 , '100_B', 'step_2', 8 ),
( 100 , '100_B', 'step_3', 9 )
) AS t(location, sub_location, step, amount);

我正在努力实现以下结果集。

Location    Sub_location    Step_1  Step_2  Step_3
-------- ------------ ------ ------ ------
100 100_A 2 7 6
100 100_B 5 8 9

我可以很容易地实现这是 MS SQL。还有我的交叉表查询,

Select * from crosstab
(
'select location, sub_location, step, amount from loc',
'select distinct step from loc'
)
as final_result(location varchar,sub_location varchar, step_1 int, step_2 int, step_3 int);

我只看到一行而不是两行。无论如何要克服 postgres 中的这个限制。

最佳答案

使用ARRAY解决复合键问题

我认为您遇到的真正问题是您的 sub_location 是您的主要标识符(名称)的一部分,用于交叉目的。而且,不是什么crosstab calls an extra column.

The "extra" columns are expected to be the same for all rows with the same row_name value.

所以本质上,构成名称的组合键必须由用户序列化。您仍然可以使用 ARRAY[location, sub_location]::text[] 将此工作序列化为 text[] 类型的 SQL ARRAY .

SELECT *
FROM crosstab(
$$ SELECT ARRAY[location, sub_location]::text[], step, amount FROM loc ORDER BY 1, 2, 3; $$,
$$ SELECT DISTINCT step FROM loc ORDER BY 1; $$
) AS t(location text[], step_1 int, step_2 int, step_3 int );

location | step_1 | step_2 | step_3
-------------+--------+--------+--------
{100,100_A} | 2 | 7 | 6
{100,100_B} | 5 | 8 | 9
(2 rows)

利用其中包含实际位置的子位置

现在,由于您特定情况下的子位置具有位置数据,我们可以通过切换顺序来缩短它。我不会将子位置存储在带有 100_ 的表中,但我们可以在这里使用它。需要明确的是,如果 location: 100, sublocation: 'A' 这是我存储它的方式,这将不起作用。

SELECT *
FROM crosstab(
$$ SELECT sub_location, location, step, amount FROM loc ORDER BY 1, 2, 3; $$,
$$ SELECT DISTINCT step FROM loc ORDER BY 1; $$
) AS t(sub_location text, location int, step_1 int, step_2 int, step_3 int );
sub_location | location | step_1 | step_2 | step_3
--------------+----------+--------+--------+--------
100_A | 100 | 2 | 7 | 6
100_B | 100 | 5 | 8 | 9
(2 rows)

不过,这消除了调用 ARRAY 的复杂性。

简化您的用例

我们也可以在此时删除 `location 或在父查询中切换顺序。

SELECT *
FROM crosstab(
$$ SELECT sub_location, step, amount FROM loc ORDER BY 1, 2, 3; $$,
$$ SELECT DISTINCT step FROM loc ORDER BY 1; $$
) AS t(location_full text, step_1 int, step_2 int, step_3 int );

location_full | step_1 | step_2 | step_3
---------------+--------+--------+--------
100_A | 2 | 7 | 6
100_B | 5 | 8 | 9
(2 rows)

不确定以上哪种方法最适合您。不要忘记 CREATE EXTENSION tablefunc; 当然,这是否比非交叉表版本更容易是完全主观的。

关于postgresql - 在具有复合键(多列)的查询上使用交叉表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43417868/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com