查询和多关系表 Postgresql
Query & multiple relationships tables Postgresql
我是第一个项目的初学者,找不到如何在一行中获得结果的解决方案。
下面我贴了部分代码:3个战士(Monika,Pawel,Tomasz) 2 styles_names (MT,K1), 2 fight_level (AM, PRO_AM)。
我怀疑我是否以正确的方式创建了这些表格,并且我正在寻找一种更好的解决方案,该解决方案允许在一行中选择所有数据(对于一名战斗机)。
我计划将结果发送到 csv 文件,因此与一名战斗机相关的所有数据必须排成一行以便进一步排序。
我将不胜感激有关如何解决它的建议。
CREATE TABLE fighters ( fighter_id INT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,fighter_name VARCHAR(20));
CREATE TABLE styles (style_id INT UNIQUE,fight_style_name VARCHAR(4),fight_level VARCHAR (8));
CREATE TABLE styles_preferred (fighter_id INT,style_id1 INT,style_id2 INT,style_id3 INT,style_id4 INT,FOREIGN KEY(fighter_id) REFERENCES fighters(fighter_id) ON DELETE SET NULL,FOREIGN KEY(style_id1) REFERENCES styles(style_id) ON DELETE SET NULL,FOREIGN KEY(style_id2) REFERENCES styles(style_id) ON DELETE SET NULL,FOREIGN KEY(style_id3) REFERENCES styles(style_id) ON DELETE SET NULL,FOREIGN KEY(style_id4) REFERENCES styles(style_id) ON DELETE SET NULL);
CREATE TABLE styles_optional (fighter_id INT,style_id1 INT,style_id2 INT,style_id3 INT,style_id4 INT,FOREIGN KEY(fighter_id) REFERENCES fighters(fighter_id) ON DELETE SET NULL,FOREIGN KEY(style_id1) REFERENCES styles(style_id) ON DELETE SET NULL,FOREIGN KEY(style_id2) REFERENCES styles(style_id) ON DELETE SET NULL,FOREIGN KEY(style_id3) REFERENCES styles(style_id) ON DELETE SET NULL,FOREIGN KEY(style_id4) REFERENCES styles(style_id) ON DELETE SET NULL);
INSERT INTO fighters (fighter_name) VALUES ('Monika'),('Paweł'),('Tomasz);
INSERT INTO styles (style_id,fight_style_name,fight_level) VALUES(2001,'MT','AM'),(2002,'MT','PRO_AM'),(2003,'K1','AM'),(2004,'K1','PRO_AM');
INSERT INTO styles_preferred(fighter_id, style_id2, style_id4) VALUES(1, 2002,2004);
INSERT INTO styles_optional(fighter_id, style_id1 ) VALUES (1, 2001);
INSERT INTO styles_preferred(fighter_id, style_id3) VALUES (2, 2003);
INSERT INTO styles_optional(fighter_id, style_id1, style_id4) VALUES (2, 2001, 2004);
INSERT INTO styles_preferred(fighter_id, style_id1) VALUES (3, 2001);
SELECT (fighters.fighter_name, CONCAT (styles.fight_style_name, styles.fight_level))FROM fighters LEFT JOIN styles_preferred ON styles_preferred.fighter_id = fighters.fighter_id LEFT JOIN styles_optional ON styles_optional.fighter_id = fighters.fighter_id LEFT JOIN styles ON styles.style_id = styles_preferred .style_id2 OR styles.style_id = styles_preferred .style_id4 OR styles.style_id = styles_optional.style_id4 WHERE styles_preferred.style_id2 = 2002 OR styles_preferred.style_id4 = 2004 OR styles_optional. style_id4 = 2004;
这就是我得到的:
row
(Monika,MTPRO_AM)
(Monika,K1PRO_AM)
(Paweł,K1PRO_AM)
这就是我想要得到的:
row
(Monika,MTPRO_AM, K1PRO_AM)
(Paweł,K1PRO_AM)
您的查询几乎您想要得到的。你需要的是string_agg after the concatenating the style data. See Demo。请注意,分隔符(: 和 /)是我添加的,如果没有我指定它们,查询将不会生成。
select (fighter_name, string_agg(styles, '/') )
from ( select
fighters.fighter_name
, CONCAT (
styles.fight_style_name
,':'
, styles.fight_level) styles
from fighters
left join styles_preferred on
styles_preferred.fighter_id = fighters.fighter_id
left join styles_optional on
styles_optional.fighter_id = fighters.fighter_id
left join styles on
styles.style_id = styles_preferred .style_id2
or styles.style_id = styles_preferred .style_id4
or styles.style_id = styles_optional.style_id4
where
styles_preferred.style_id2 = 2002
or styles_preferred.style_id4 = 2004
or styles_optional. style_id4 = 2004 ) fs
group by fighter_name;
旁注:您迫切需要 格式化您的 SQL。您在一行中发布了一个 540 个字符的查询,我当然希望这只是粘贴时的一个错误。这是因为要求向右滚动那么多的查询实际上是不可读的。不幸的是,您的其他陈述也遭受同样的命运,只是没有那么糟糕。上面的格式是由 DBeaver 的内置格式功能生成的。几乎所有的数据库接口都提供一个,使用它们。
我是第一个项目的初学者,找不到如何在一行中获得结果的解决方案。
下面我贴了部分代码:3个战士(Monika,Pawel,Tomasz) 2 styles_names (MT,K1), 2 fight_level (AM, PRO_AM)。 我怀疑我是否以正确的方式创建了这些表格,并且我正在寻找一种更好的解决方案,该解决方案允许在一行中选择所有数据(对于一名战斗机)。 我计划将结果发送到 csv 文件,因此与一名战斗机相关的所有数据必须排成一行以便进一步排序。 我将不胜感激有关如何解决它的建议。
CREATE TABLE fighters ( fighter_id INT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,fighter_name VARCHAR(20));
CREATE TABLE styles (style_id INT UNIQUE,fight_style_name VARCHAR(4),fight_level VARCHAR (8));
CREATE TABLE styles_preferred (fighter_id INT,style_id1 INT,style_id2 INT,style_id3 INT,style_id4 INT,FOREIGN KEY(fighter_id) REFERENCES fighters(fighter_id) ON DELETE SET NULL,FOREIGN KEY(style_id1) REFERENCES styles(style_id) ON DELETE SET NULL,FOREIGN KEY(style_id2) REFERENCES styles(style_id) ON DELETE SET NULL,FOREIGN KEY(style_id3) REFERENCES styles(style_id) ON DELETE SET NULL,FOREIGN KEY(style_id4) REFERENCES styles(style_id) ON DELETE SET NULL);
CREATE TABLE styles_optional (fighter_id INT,style_id1 INT,style_id2 INT,style_id3 INT,style_id4 INT,FOREIGN KEY(fighter_id) REFERENCES fighters(fighter_id) ON DELETE SET NULL,FOREIGN KEY(style_id1) REFERENCES styles(style_id) ON DELETE SET NULL,FOREIGN KEY(style_id2) REFERENCES styles(style_id) ON DELETE SET NULL,FOREIGN KEY(style_id3) REFERENCES styles(style_id) ON DELETE SET NULL,FOREIGN KEY(style_id4) REFERENCES styles(style_id) ON DELETE SET NULL);
INSERT INTO fighters (fighter_name) VALUES ('Monika'),('Paweł'),('Tomasz);
INSERT INTO styles (style_id,fight_style_name,fight_level) VALUES(2001,'MT','AM'),(2002,'MT','PRO_AM'),(2003,'K1','AM'),(2004,'K1','PRO_AM');
INSERT INTO styles_preferred(fighter_id, style_id2, style_id4) VALUES(1, 2002,2004);
INSERT INTO styles_optional(fighter_id, style_id1 ) VALUES (1, 2001);
INSERT INTO styles_preferred(fighter_id, style_id3) VALUES (2, 2003);
INSERT INTO styles_optional(fighter_id, style_id1, style_id4) VALUES (2, 2001, 2004);
INSERT INTO styles_preferred(fighter_id, style_id1) VALUES (3, 2001);
SELECT (fighters.fighter_name, CONCAT (styles.fight_style_name, styles.fight_level))FROM fighters LEFT JOIN styles_preferred ON styles_preferred.fighter_id = fighters.fighter_id LEFT JOIN styles_optional ON styles_optional.fighter_id = fighters.fighter_id LEFT JOIN styles ON styles.style_id = styles_preferred .style_id2 OR styles.style_id = styles_preferred .style_id4 OR styles.style_id = styles_optional.style_id4 WHERE styles_preferred.style_id2 = 2002 OR styles_preferred.style_id4 = 2004 OR styles_optional. style_id4 = 2004;
这就是我得到的:
row |
---|
(Monika,MTPRO_AM) |
(Monika,K1PRO_AM) |
(Paweł,K1PRO_AM) |
这就是我想要得到的:
row |
---|
(Monika,MTPRO_AM, K1PRO_AM) |
(Paweł,K1PRO_AM) |
您的查询几乎您想要得到的。你需要的是string_agg after the concatenating the style data. See Demo。请注意,分隔符(: 和 /)是我添加的,如果没有我指定它们,查询将不会生成。
select (fighter_name, string_agg(styles, '/') )
from ( select
fighters.fighter_name
, CONCAT (
styles.fight_style_name
,':'
, styles.fight_level) styles
from fighters
left join styles_preferred on
styles_preferred.fighter_id = fighters.fighter_id
left join styles_optional on
styles_optional.fighter_id = fighters.fighter_id
left join styles on
styles.style_id = styles_preferred .style_id2
or styles.style_id = styles_preferred .style_id4
or styles.style_id = styles_optional.style_id4
where
styles_preferred.style_id2 = 2002
or styles_preferred.style_id4 = 2004
or styles_optional. style_id4 = 2004 ) fs
group by fighter_name;
旁注:您迫切需要 格式化您的 SQL。您在一行中发布了一个 540 个字符的查询,我当然希望这只是粘贴时的一个错误。这是因为要求向右滚动那么多的查询实际上是不可读的。不幸的是,您的其他陈述也遭受同样的命运,只是没有那么糟糕。上面的格式是由 DBeaver 的内置格式功能生成的。几乎所有的数据库接口都提供一个,使用它们。