问题
I have prepared a simple SQL Fiddle for my question -
In a word game written in Pl/pgSQL for PostgreSQL 10.2 player moves are stored in the table:
CREATE TABLE words_scores (
mid bigint NOT NULL REFERENCES words_moves ON DELETE CASCADE,
gid integer NOT NULL REFERENCES words_games ON DELETE CASCADE,
uid integer NOT NULL REFERENCES words_users ON DELETE CASCADE,
word text NOT NULL CHECK(word ~ '^[A-Z]{2,}$'),
score integer NOT NULL CHECK(score >= 0)
);
Here it is filled with some test data:
INSERT INTO words_scores (mid, gid, uid, word, score) VALUES
(230, 209, 7, 'XY', 5),
(230, 209, 7, 'XYZ', 15),
(230, 209, 7, 'XAB', 13);
In a stored function I need to generate a string, which would contain all words played by a player in a certain move.
This is close to what I need and returns XY, XYZ, XAB
:
SELECT STRING_AGG(word, ', ') FROM words_scores WHERE mid=230;
However I also need to have the score of each word in brackets, following each words as in:
XY (5), XYZ (15), XAB (13)
Is there maybe some clever use of Aggregate Functions possible to achieve that?
回答1:
Use FORMAT (as described in the manual) to format your string before aggregation:
SELECT STRING_AGG(FORMAT('%s (%s)', word, score), ', ') FROM words_scores WHERE mid=230;
Here's the updated SQL Fiddle.
来源:https://stackoverflow.com/questions/49009775/constructing-a-string-out-of-several-records-with-2-columns