如何在没有 "duplicating" 聚合数据的情况下使用两个聚合函数连接多个表?
How to join multiple tables using two aggregate functions without "duplicating" aggregated data?
我正在尝试每行显示一首 tune
(歌曲)以及与该特定曲调 tune_id
相关的所有数据,如果与 [=17= 相关的字段有更多条目] 我希望通过 ' & '
聚合和连接数据。但是,我不明白为什么 string_agg(artist, ' & ')
为 tune_id
的每个 producer
条目复制艺术家的名字。此外,string_agg(producer, ' & ')
函数也不会显示所需的结果。我假设我错误地使用了 GROUP BY
或两个聚合函数。
我目前是运行 PostgreSQL 9.1.16,虽然它会在几天内升级到最新版本。
这是一个 SQLFiddle 的所有设置,如下所述。
数据库结构为:
CREATE TABLE tunes (
tune_id SERIAL PRIMARY KEY,
tune TEXT NOT NULL
);
CREATE TABLE artistnames (
artistname_id SERIAL PRIMARY KEY,
artist TEXT UNIQUE NOT NULL
);
CREATE TABLE artists (
artist_id SERIAL PRIMARY KEY,
artistname_id SERIAL REFERENCES artistnames (artistname_id),
tune_id SERIAL REFERENCES tunes (tune_id)
);
CREATE TABLE producernames (
producername_id SERIAL PRIMARY KEY,
producer TEXT UNIQUE NOT NULL
);
CREATE TABLE producers (
producer_id SERIAL PRIMARY KEY,
producername_id SERIAL REFERENCES producernames (producername_id),
tune_id SERIAL REFERENCES tunes (tune_id)
);
用于测试数据库的虚拟数据是:
TRUNCATE TABLE tunes, artistnames, artists, producernames, producers CASCADE;
ALTER SEQUENCE tunes_tune_id_seq RESTART WITH 1;
ALTER SEQUENCE artistnames_artistname_id_seq RESTART WITH 1;
ALTER SEQUENCE artists_artist_id_seq RESTART WITH 1;
ALTER SEQUENCE producernames_producername_id_seq RESTART WITH 1;
ALTER SEQUENCE producers_producer_id_seq RESTART WITH 1;
INSERT INTO tunes (tune)
VALUES ('Only Takes Love'), ('Some Boy');
INSERT INTO artistnames (artist)
VALUES ('Sizzla'), ('Tanto Metro'), ('Devonte');
INSERT INTO artists (artistname_id, tune_id)
VALUES (1, 1), (2, 2), (3, 2);
INSERT INTO producernames (producer)
VALUES ('Brad "Riprock" Daymond'), ('Alexander Greggs'), ('Dennis');
INSERT INTO producers (producername_id, tune_id)
VALUES (1, 1), (2, 1), (3, 1), (1, 2), (3, 2);
我正在使用的查询如下所示:
SELECT
string_agg(artist, ' & ') AS artist,
tune,
string_agg(producer, ' & ') AS producer
FROM tunes
FULL JOIN artists USING (tune_id)
FULL JOIN artistnames USING (artistname_id)
FULL JOIN producers USING (tune_id)
FULL JOIN producernames USING (producername_id)
GROUP BY tune;
此查询返回的结果如下所示:
+-----------------------------------------------+-----------------+-------------------------------------------------------------------+
| artist | tune | producer |
+-----------------------------------------------+-----------------+-------------------------------------------------------------------+
| Sizzla & Sizzla & Sizzla | Only Takes Love | Brad "Riprock" Daymond & Alexander Greggs & Dennis |
+-----------------------------------------------+-----------------+-------------------------------------------------------------------+
| Tanto Metro & Tanto Metro & Devonte & Devonte | Some Boy | Brad "Riprock" Daymond & Dennis & Brad "Riprock" Daymond & Dennis |
+-----------------------------------------------+-----------------+-------------------------------------------------------------------+
这是我试图获得的结果:
+-----------------------+-----------------+----------------------------------------------------+
| artist | tune | producer |
+-----------------------+-----------------+----------------------------------------------------+
| Sizzla | Only Takes Love | Brad "Riprock" Daymond & Alexander Greggs & Dennis |
+-----------------------+-----------------+----------------------------------------------------+
| Tanto Metro & Devonte | Some Boy | Brad "Riprock" Daymond & Dennis |
+-----------------------+-----------------+----------------------------------------------------+
编辑: 我不太确定 title/question 是否适合所描述的问题,如果有人有更好的 title/question 建议适合我的问题,让我知道。
SELECT
string_agg(distinct(artist), ' & ') AS artist,
tune,
string_agg(distinct(producer), ' & ') AS producer
FROM
tunes
left join (
artists
left JOIN
artistnames USING (artistname_id)
) a USING (tune_id)
left JOIN (
producers
left JOIN
producernames USING (producername_id)
) b USING (tune_id)
GROUP BY tune;
我正在尝试每行显示一首 tune
(歌曲)以及与该特定曲调 tune_id
相关的所有数据,如果与 [=17= 相关的字段有更多条目] 我希望通过 ' & '
聚合和连接数据。但是,我不明白为什么 string_agg(artist, ' & ')
为 tune_id
的每个 producer
条目复制艺术家的名字。此外,string_agg(producer, ' & ')
函数也不会显示所需的结果。我假设我错误地使用了 GROUP BY
或两个聚合函数。
我目前是运行 PostgreSQL 9.1.16,虽然它会在几天内升级到最新版本。
这是一个 SQLFiddle 的所有设置,如下所述。
数据库结构为:
CREATE TABLE tunes (
tune_id SERIAL PRIMARY KEY,
tune TEXT NOT NULL
);
CREATE TABLE artistnames (
artistname_id SERIAL PRIMARY KEY,
artist TEXT UNIQUE NOT NULL
);
CREATE TABLE artists (
artist_id SERIAL PRIMARY KEY,
artistname_id SERIAL REFERENCES artistnames (artistname_id),
tune_id SERIAL REFERENCES tunes (tune_id)
);
CREATE TABLE producernames (
producername_id SERIAL PRIMARY KEY,
producer TEXT UNIQUE NOT NULL
);
CREATE TABLE producers (
producer_id SERIAL PRIMARY KEY,
producername_id SERIAL REFERENCES producernames (producername_id),
tune_id SERIAL REFERENCES tunes (tune_id)
);
用于测试数据库的虚拟数据是:
TRUNCATE TABLE tunes, artistnames, artists, producernames, producers CASCADE;
ALTER SEQUENCE tunes_tune_id_seq RESTART WITH 1;
ALTER SEQUENCE artistnames_artistname_id_seq RESTART WITH 1;
ALTER SEQUENCE artists_artist_id_seq RESTART WITH 1;
ALTER SEQUENCE producernames_producername_id_seq RESTART WITH 1;
ALTER SEQUENCE producers_producer_id_seq RESTART WITH 1;
INSERT INTO tunes (tune)
VALUES ('Only Takes Love'), ('Some Boy');
INSERT INTO artistnames (artist)
VALUES ('Sizzla'), ('Tanto Metro'), ('Devonte');
INSERT INTO artists (artistname_id, tune_id)
VALUES (1, 1), (2, 2), (3, 2);
INSERT INTO producernames (producer)
VALUES ('Brad "Riprock" Daymond'), ('Alexander Greggs'), ('Dennis');
INSERT INTO producers (producername_id, tune_id)
VALUES (1, 1), (2, 1), (3, 1), (1, 2), (3, 2);
我正在使用的查询如下所示:
SELECT
string_agg(artist, ' & ') AS artist,
tune,
string_agg(producer, ' & ') AS producer
FROM tunes
FULL JOIN artists USING (tune_id)
FULL JOIN artistnames USING (artistname_id)
FULL JOIN producers USING (tune_id)
FULL JOIN producernames USING (producername_id)
GROUP BY tune;
此查询返回的结果如下所示:
+-----------------------------------------------+-----------------+-------------------------------------------------------------------+
| artist | tune | producer |
+-----------------------------------------------+-----------------+-------------------------------------------------------------------+
| Sizzla & Sizzla & Sizzla | Only Takes Love | Brad "Riprock" Daymond & Alexander Greggs & Dennis |
+-----------------------------------------------+-----------------+-------------------------------------------------------------------+
| Tanto Metro & Tanto Metro & Devonte & Devonte | Some Boy | Brad "Riprock" Daymond & Dennis & Brad "Riprock" Daymond & Dennis |
+-----------------------------------------------+-----------------+-------------------------------------------------------------------+
这是我试图获得的结果:
+-----------------------+-----------------+----------------------------------------------------+
| artist | tune | producer |
+-----------------------+-----------------+----------------------------------------------------+
| Sizzla | Only Takes Love | Brad "Riprock" Daymond & Alexander Greggs & Dennis |
+-----------------------+-----------------+----------------------------------------------------+
| Tanto Metro & Devonte | Some Boy | Brad "Riprock" Daymond & Dennis |
+-----------------------+-----------------+----------------------------------------------------+
编辑: 我不太确定 title/question 是否适合所描述的问题,如果有人有更好的 title/question 建议适合我的问题,让我知道。
SELECT
string_agg(distinct(artist), ' & ') AS artist,
tune,
string_agg(distinct(producer), ' & ') AS producer
FROM
tunes
left join (
artists
left JOIN
artistnames USING (artistname_id)
) a USING (tune_id)
left JOIN (
producers
left JOIN
producernames USING (producername_id)
) b USING (tune_id)
GROUP BY tune;