用最后一个值在递归 SQL 上填充空 space
Fill empty space on recursive SQL with last value
这是我用来从 table 获取数据的 SQL 查询,其中包含父子值:
WITH RECURSIVE cte AS
(
SELECT array[r.term1_id, r.term2_id] AS path
FROM temp_table r
LEFT JOIN temp_table r0 ON r0.term1_id = r.term2_id
WHERE r0.term1_id IS NULL
UNION ALL
SELECT r.term1_id || c.path
FROM cte c
JOIN temp_table r ON r.term2_id = c.path[1]
)
SELECT path
FROM cte
ORDER BY path;
结果是这样的:
"{1,5,6,1452}"
"{1,5,6,1470,1475}"
如何填充第一个数组的最后 space 以获得类似的东西?
"{1,5,6,1452,1452}"
"{1,5,6,1470,1475}"
所以我想重复最后一个非空值,直到我覆盖每个级别。
答案:
这是一个功能声明
CREATE OR REPLACE FUNCTION fill_with_last_element(arr anyarray, n INTEGER)
RETURNS anyarray LANGUAGE plpgsql as $$
DECLARE
l int = array_length(arr,1);
BEGIN
RETURN CASE
WHEN l > n THEN arr
ELSE arr || array_fill(arr[l], array[n- l])
END;
END $$;
WITH RECURSIVE cte(path) AS (
SELECT array[r.term1_id, r.term2_id] AS path
FROM temp_table r
LEFT JOIN temp_table r0 ON r0.term1_id = r.term2_id
WHERE r0.term1_id IS NULL
UNION ALL
SELECT r.term1_id || c.path
FROM cte c
JOIN temp_table r ON r.term2_id = c.path[1]
),
max_len AS (
SELECT max(array_length(path, 1)) max_len
FROM cte
)
SELECT fill_with_last_element(path, max_len)
FROM cte
CROSS JOIN max_len
ORDER BY path;
您无法生成长度相等的数组,因为您不知道查询终止前的长度。您应该修改结果。这个函数会有帮助:
create or replace function fill_with_last_element(arr anyarray, n integer)
returns anyarray language plpgsql as $$
declare
l int = array_length(arr,1);
begin
return case
when l > n then arr
else arr || array_fill(arr[l], array[n- l])
end;
end $$;
示例:
with cte(path) as (
values
('{1,5,6,1452}'::int[]),
('{1,5,6,1470,1475}')
),
max_len as (
select max(array_length(path, 1)) max_len
from cte
)
select fill_with_last_element(path, max_len)
from cte
cross join max_len
fill_with_last_element
------------------------
{1,5,6,1452,1452}
{1,5,6,1470,1475}
(2 rows)
这是我用来从 table 获取数据的 SQL 查询,其中包含父子值:
WITH RECURSIVE cte AS
(
SELECT array[r.term1_id, r.term2_id] AS path
FROM temp_table r
LEFT JOIN temp_table r0 ON r0.term1_id = r.term2_id
WHERE r0.term1_id IS NULL
UNION ALL
SELECT r.term1_id || c.path
FROM cte c
JOIN temp_table r ON r.term2_id = c.path[1]
)
SELECT path
FROM cte
ORDER BY path;
结果是这样的:
"{1,5,6,1452}"
"{1,5,6,1470,1475}"
如何填充第一个数组的最后 space 以获得类似的东西?
"{1,5,6,1452,1452}"
"{1,5,6,1470,1475}"
所以我想重复最后一个非空值,直到我覆盖每个级别。
答案:
这是一个功能声明
CREATE OR REPLACE FUNCTION fill_with_last_element(arr anyarray, n INTEGER)
RETURNS anyarray LANGUAGE plpgsql as $$
DECLARE
l int = array_length(arr,1);
BEGIN
RETURN CASE
WHEN l > n THEN arr
ELSE arr || array_fill(arr[l], array[n- l])
END;
END $$;
WITH RECURSIVE cte(path) AS (
SELECT array[r.term1_id, r.term2_id] AS path
FROM temp_table r
LEFT JOIN temp_table r0 ON r0.term1_id = r.term2_id
WHERE r0.term1_id IS NULL
UNION ALL
SELECT r.term1_id || c.path
FROM cte c
JOIN temp_table r ON r.term2_id = c.path[1]
),
max_len AS (
SELECT max(array_length(path, 1)) max_len
FROM cte
)
SELECT fill_with_last_element(path, max_len)
FROM cte
CROSS JOIN max_len
ORDER BY path;
您无法生成长度相等的数组,因为您不知道查询终止前的长度。您应该修改结果。这个函数会有帮助:
create or replace function fill_with_last_element(arr anyarray, n integer)
returns anyarray language plpgsql as $$
declare
l int = array_length(arr,1);
begin
return case
when l > n then arr
else arr || array_fill(arr[l], array[n- l])
end;
end $$;
示例:
with cte(path) as (
values
('{1,5,6,1452}'::int[]),
('{1,5,6,1470,1475}')
),
max_len as (
select max(array_length(path, 1)) max_len
from cte
)
select fill_with_last_element(path, max_len)
from cte
cross join max_len
fill_with_last_element
------------------------
{1,5,6,1452,1452}
{1,5,6,1470,1475}
(2 rows)