PostgreSQL 为每个 array_agg 元素创建列而不是逗号分隔
PostgreSQL create column for each array_agg element instead of comma-separate
我想为从返回的每个 string_agg 元素强制创建一个新列(即,Fiction、Mystery 将在一列中 'Fiction',在下一列中 'Mystery')这个查询,以及 2.) 我需要能够将标签列最多扩展到五个标签:
SELECT books.isbn_13 as "ISBN", title as "Title",
author as "Author",
string_agg(tag_name, ', ') as "Tags"
FROM books
LEFT JOIN book_tags on books.isbn_13 = book_tags.isbn_13
GROUP BY books.isbn_13;
现在一切看起来都不错,除了我想要为每个标签一列而不是逗号分隔值。这是我的当前结果:
ISBN | Title | Author | Tags
1111111111111 | The Adventures of Steve | Russell Barron | Fiction, Mystery
2222222222222 | It's all a mystery to me | Mystery Man | Mystery
3333333333333 | Biography of a Programmer | Solo Artist | Biography
4444444444444 | Steve and Russel go to Mars | Russell Groupon |
6666666666666 | Newest Book you Must Have | Newbie Onthescene |
期望的结果(将标签分成多个列):
ISBN | Title | Author | Tag1 | Tag2 | Tag3 | Tag4
1111111111111 | The Adventures of Steve | Russell Barron | Fiction | Mystery | Male Protagonists | Fantasy|
2222222222222 | It's all a mystery to me | Mystery Man | Mystery
3333333333333 | Biography of a Programmer | Solo Artist | Biography
4444444444444 | Steve and Russel go to Mars | Russell Groupon |
6666666666666 | Newest Book you Must Have | Newbie Onthescene |
SCHEMA for books table (parent):
CREATE TABLE public.books
(
isbn_13 character varying(13) COLLATE pg_catalog."default" NOT NULL,
title character varying(100) COLLATE pg_catalog."default",
author character varying(80) COLLATE pg_catalog."default",
publish_date date,
price numeric(6,2),
content bytea,
CONSTRAINT books_pkey PRIMARY KEY (isbn_13)
)
SCHEMA book_tags table:
CREATE TABLE public.book_tags
(
isbn_13 character varying(13) COLLATE pg_catalog."default" NOT NULL,
tag_name character varying(30) COLLATE pg_catalog."default" NOT NULL,
CONSTRAINT book_tags_pkey PRIMARY KEY (isbn_13, tag_name),
CONSTRAINT book_tags_isbn_13_fkey FOREIGN KEY (isbn_13)
REFERENCES public.books (isbn_13) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE CASCADE
)
我研究了 group by,crosstab/pivot 几个小时的资源,但没有成功。这看起来应该是一件简单的事情,但我是一个初学者,还没有找到答案。在此先感谢您的指导。
With CTE as (
SELECT books.isbn_13 as "ISBN",
title as "Title",
author as "Author",
tag_name as "Tag",
row_number() over (partition by books.isbn_13) as rn
FROM books
LEFT JOIN book_tags
on books.isbn_13 = book_tags.isbn_13
)
SELECT "ISBN", "Title", "Author",
MAX( CASE WHEN rn = 1 THEN Tag END) as Tag1,
MAX( CASE WHEN rn = 2 THEN Tag END) as Tag2,
MAX( CASE WHEN rn = 3 THEN Tag END) as Tag3,
MAX( CASE WHEN rn = 4 THEN Tag END) as Tag4,
MAX( CASE WHEN rn = 5 THEN Tag END) as Tag5
FROM CTE
GROUP BY "ISBN", "Title", "Author";
我想为从返回的每个 string_agg 元素强制创建一个新列(即,Fiction、Mystery 将在一列中 'Fiction',在下一列中 'Mystery')这个查询,以及 2.) 我需要能够将标签列最多扩展到五个标签:
SELECT books.isbn_13 as "ISBN", title as "Title",
author as "Author",
string_agg(tag_name, ', ') as "Tags"
FROM books
LEFT JOIN book_tags on books.isbn_13 = book_tags.isbn_13
GROUP BY books.isbn_13;
现在一切看起来都不错,除了我想要为每个标签一列而不是逗号分隔值。这是我的当前结果:
ISBN | Title | Author | Tags
1111111111111 | The Adventures of Steve | Russell Barron | Fiction, Mystery
2222222222222 | It's all a mystery to me | Mystery Man | Mystery
3333333333333 | Biography of a Programmer | Solo Artist | Biography
4444444444444 | Steve and Russel go to Mars | Russell Groupon |
6666666666666 | Newest Book you Must Have | Newbie Onthescene |
期望的结果(将标签分成多个列):
ISBN | Title | Author | Tag1 | Tag2 | Tag3 | Tag4
1111111111111 | The Adventures of Steve | Russell Barron | Fiction | Mystery | Male Protagonists | Fantasy|
2222222222222 | It's all a mystery to me | Mystery Man | Mystery
3333333333333 | Biography of a Programmer | Solo Artist | Biography
4444444444444 | Steve and Russel go to Mars | Russell Groupon |
6666666666666 | Newest Book you Must Have | Newbie Onthescene |
SCHEMA for books table (parent):
CREATE TABLE public.books
(
isbn_13 character varying(13) COLLATE pg_catalog."default" NOT NULL,
title character varying(100) COLLATE pg_catalog."default",
author character varying(80) COLLATE pg_catalog."default",
publish_date date,
price numeric(6,2),
content bytea,
CONSTRAINT books_pkey PRIMARY KEY (isbn_13)
)
SCHEMA book_tags table:
CREATE TABLE public.book_tags
(
isbn_13 character varying(13) COLLATE pg_catalog."default" NOT NULL,
tag_name character varying(30) COLLATE pg_catalog."default" NOT NULL,
CONSTRAINT book_tags_pkey PRIMARY KEY (isbn_13, tag_name),
CONSTRAINT book_tags_isbn_13_fkey FOREIGN KEY (isbn_13)
REFERENCES public.books (isbn_13) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE CASCADE
)
我研究了 group by,crosstab/pivot 几个小时的资源,但没有成功。这看起来应该是一件简单的事情,但我是一个初学者,还没有找到答案。在此先感谢您的指导。
With CTE as (
SELECT books.isbn_13 as "ISBN",
title as "Title",
author as "Author",
tag_name as "Tag",
row_number() over (partition by books.isbn_13) as rn
FROM books
LEFT JOIN book_tags
on books.isbn_13 = book_tags.isbn_13
)
SELECT "ISBN", "Title", "Author",
MAX( CASE WHEN rn = 1 THEN Tag END) as Tag1,
MAX( CASE WHEN rn = 2 THEN Tag END) as Tag2,
MAX( CASE WHEN rn = 3 THEN Tag END) as Tag3,
MAX( CASE WHEN rn = 4 THEN Tag END) as Tag4,
MAX( CASE WHEN rn = 5 THEN Tag END) as Tag5
FROM CTE
GROUP BY "ISBN", "Title", "Author";