postgresql中的递归函数
我有这张桌子:postgresql中的递归函数,sql,postgresql,Sql,Postgresql,我有这张桌子: CREATE TABLE players ( winner CHARACTER VARYING(50) NOT NULL , successor CHARACTER VARYING(50) NOT NULL , data NUMERIC(6,2) NOT NULL , CONSTRAINT pk_win_succ PRIMARY KEY (winner, successor) );
CREATE TABLE players
(
winner CHARACTER VARYING(50) NOT NULL ,
successor CHARACTER VARYING(50) NOT NULL ,
data NUMERIC(6,2) NOT NULL ,
CONSTRAINT pk_win_succ PRIMARY KEY (winner, successor)
);
数据:
INSERT INTO players VALUES
('Helen','Sharon',12),
('Claudia','Steffi',35),
('Sharon','Penny',5),
('Meg','Claudia',21),
('Penny','Meg',3)
('Steffi','Helen',230);
我需要做的是一个SQL查询,它为我提供了玩家之间可能的不同组合
如果我选择球员Sharon作为首字母,选择球员Meg作为最终字母,则查询结果应为:
Initial | Final | List of winners | Total Data | Number of Winners |
Sharon | Meg | Sharon - Penny - Meg | 8 | 3
Initial | Final | List of winners | Total Data | Number of Winners |
Claudia | Sharon | Claudia - Steffi - Helen - Sharon | 277 | 4
如果我选择球员克劳迪娅作为首字母,选择球员沙龙作为最终字母,那么查询结果应该是:
Initial | Final | List of winners | Total Data | Number of Winners |
Sharon | Meg | Sharon - Penny - Meg | 8 | 3
Initial | Final | List of winners | Total Data | Number of Winners |
Claudia | Sharon | Claudia - Steffi - Helen - Sharon | 277 | 4
谢谢大家! 可以通过递归查询构建从Sharon到Meg的链:
WITH RECURSIVE chain(winner, successor, data, active) AS (
SELECT winner, successor, data, true
FROM players
WHERE winner = 'Sharon'
UNION ALL
SELECT p.winner, p.successor, p.data
,CASE WHEN p.successor = 'Meg' OR NOT c.active THEN false ELSE true END
FROM players p
JOIN chain c ON (p.winner = c.successor AND c.active)
)
SELECT * FROM chain
结果:
Sharon;Penny;5.00;t
Penny;Meg;3.00;f
然后,可以将结果集聚合为所需的格式:
WITH RECURSIVE chain(winner, successor, data, active) AS (
SELECT winner, successor, data, true
FROM players
WHERE winner = 'Sharon'
UNION ALL
SELECT p.winner, p.successor, p.data
,CASE WHEN p.successor = 'Meg' OR NOT c.active THEN false ELSE true END
FROM players p
JOIN chain c ON (p.winner = c.successor AND c.active)
)
SELECT 'Sharon' AS Initial
,'Meg' AS Final
,'Sharon - ' || string_agg(successor, ' - ') AS Winners
,sum(data) AS Total
,count(*) + 1 AS WinnerCount
FROM chain
或参数化:
PREPARE plan(text, text) AS
WITH RECURSIVE chain(winner, successor, data, active) AS (
SELECT winner, successor, data, true
FROM players
WHERE winner = $1
UNION ALL
SELECT p.winner, p.successor, p.data
,CASE WHEN p.successor = $2 OR NOT c.active THEN false ELSE true END
FROM players p
JOIN chain c ON (p.winner = c.successor AND c.active)
)
SELECT $1 AS Initial
,$2 AS Final
,$1 || ' - ' || string_agg(successor, ' - ') AS Winners
,sum(data) AS Total
,count(*) + 1 AS WinnerCount
FROM chain
;
EXECUTE plan('Sharon', 'Meg');
EXECUTE plan('Claudia', 'Sharon');
你是在寻找一条从一个玩家到另一个玩家的“链条”吗。这是什么?如果是这样,你最好的朋友就是一个图形数据库。