Postgresql数组_agg、内部连接和左连接问题
我的一个问题有点小问题。此查询的目标是获取用户的所有table1项及其信息。正如您所看到的,数据模型非常复杂(有充分的理由),这需要一个大查询(我的目标是只通过一个查询收集所有内容) 以下是数据模型: 我想要的是:Postgresql数组_agg、内部连接和左连接问题,sql,postgresql,join,left-join,inner-join,Sql,Postgresql,Join,Left Join,Inner Join,我的一个问题有点小问题。此查询的目标是获取用户的所有table1项及其信息。正如您所看到的,数据模型非常复杂(有充分的理由),这需要一个大查询(我的目标是只通过一个查询收集所有内容) 以下是数据模型: 我想要的是: 所有T1信息 一个T1项的所有T2信息(这是一个1对n的关系,所以我将使用array_agg) 一个T1项目的所有T3信息 一个T1项目的所有T4信息 一个T1项目的所有T6信息 T1项目的i18n信息P 以下是表1\u表2和表4\u表6选择*: table1_id |
- 所有T1信息
- 一个T1项的所有T2信息(这是一个1对n的关系,所以我将使用array_agg)
- 一个T1项目的所有T3信息
- 一个T1项目的所有T4信息
- 一个T1项目的所有T6信息
- T1项目的i18n信息P
table1_id | table2_id
-------------+---------------
item2id | table2item1
item4id | table2item2
item4id | table2item1
item5id | table2item3
item5id | table2item2
table4_id | table6_id
------------------+--------------------
table4item1 | table6item1
table4item1 | table6item2
table4item2 | table6item2
table4item3 | table6item3
table4item1 | table6item3
table4item2 | table6item3
下面是带有id的Table1 SELECT及其外键
table1_id | table3_id
------------------------
item1id | table3item1
item2id | table3item1
item6id | table3item4
item3id | table3item2
item4id | table3item2
item5id | table3item3
表3相同:
table3_id | table4_id
------------+--------------
table3item1 | table4item1
table3item4 | table4item1
table3item2 | table4item2
table3item3 | table4item3
最后,我的问题是:
SELECT t1.id,
na.name,
array_to_json(array_agg(row_to_json(t2))) AS table2items,
array_to_json(array_agg(row_to_json(t6))) AS table6items
FROM table1 t1
INNER JOIN table1_i18n na ON na.table1_id = t1.id
INNER JOIN table3 t3 ON t3.id = t1.table3_id
INNER JOIN table4 t4 ON t4.id = t3.table4_id
LEFT JOIN table1_table2 t1t2 ON t1t2.table1_id = t1.id
LEFT JOIN table2 t2 ON t2.id = t1t2.table2_id
LEFT JOIN table4_table6 t5_t6 ON t5_t6.table5_id = t3.table4_id
LEFT JOIN table6 t6 ON t6.id = t5_t6.table6_id
WHERE t1.user_id = 'myuserid' AND na.lang = 'en_US'
GROUP BY t1.id, na.name, t4.id
ORDER BY t1.id;
结果如下:
id | name | table3_id | table4_id | table2items | table6items
-------------+------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
item1id | MyFirstItem | table3item1 | table4item1 | [null,null,null] | [{"id":"table6item1"},{"id":"table6item2"},{"id":"table6item3"}]
item2id | MySecondItem | table3item1 | table4item1 | [{"table2item1","data1":"damage","data2":10},{"id":"table2item1","data1":"damage","data2":10},{"id":"table2item1","data1":"damage","data2":10}] | [{"id":"table6item1"},{"id":"table6item2"},{"id":"table6item3"}]
item3id | MyThirdItem | table3item2 | table4item2 | [null,null] | [{"id":"table6item2"},{"id":"table6item3"}]
item4id | MyFourthItem | table3item2 | table4item2 | [{"id":"table2item2","data1":"range","data2":20},{"id":"table2item1","data1":"damage","data2":10},{"id":"table2item2","data1":"range","data2":20},{"id":"table2item1","data1":"damage","data2":10}] | [{"id":"table6item2"},{"id":"table6item3"},{"id":"table6item3"},{"id":"table6item2"}]
item5id | MyFifthItem | table3item3 | table4item3 | [{"id":"table2item3","data1":"range","data2":20},{"id":"table2item2","data1":"range","data2":20}] | [{"id":"table6item3"},{"id":"table6item3"}]
item6id | MySixthItem | table3item4 | table4item1 | [null,null,null] | [{"id":"table6item2"},{"id":"table6item1"},{"id":"table6item3"}]
嗯,我这里有个问题。如您所见,我的table2\u项目和table6\u项目数组的大小相同。我不知道这样做的原因,但似乎我遗漏了什么。
更糟糕的是,此查询不使用空值填充此数组,而是创建不应出现的重复项
详情:
- 第1项和第6项有相同的问题:没有表2的链接,表6中有3项。我最终得到了表2\u项的数组[null,null,null]
- item2有3个到表6的链接,1个到表2的链接。我最终得到了数组中相同table2对象的3倍
- 项目4。。。我不知道这里发生了什么。每个数组中应该有2个东西,我有4个(重复)
- 第五项:你可以清楚地看到复制品
SELECT t1.id,
na.name,
array_to_json(array_agg(row_to_json(t2))) AS table2items,
FROM table1 t1
INNER JOIN table1_i18n na ON na.table1_id = t1.id
INNER JOIN table3 t3 ON t3.id = t1.table3_id
INNER JOIN table4 t4 ON t4.id = t3.table4_id
LEFT JOIN table1_table2 t1t2 ON t1t2.table1_id = t1.id
LEFT JOIN table2 t2 ON t2.id = t1t2.table2_id
WHERE t1.user_id = 'myuserid' AND na.lang = 'en_US'
GROUP BY t1.id, na.name, t4.id
ORDER BY t1.id;
单靠它,它就能完美地工作。t6也一样。只有当我试图同时收集所有东西时,我才会遇到一些问题
如果不够清楚,请询问详细信息。解释这样一个问题真的不容易:)。不要这样匿名化和混淆您的模式。这让阅读变得很困难——在你的情况下,完全不可能。对不起……我已经放弃了阅读这个枯燥无味的问题的想法。不过,我建议您实际了解join、groupby和aggregate函数的作用,因为这些概念在您的头脑中似乎都不清楚。此外,我建议不要像您尝试的那样运行“一次完成所有任务”类型的查询;在单独的查询中获取t2和t6数据-并且不使用json/array\u agg lunacy。谢谢@Denis。我会把问题改清楚。我对join、groupby和aggregate有一两点了解,如果我只需要其中一个数组,就足以让这个查询工作。但我遗漏了一些东西,这正是我在这里发帖的原因。我可以通过两个查询获得数据,没有任何问题,我宁愿只使用一个查询来提高性能和代码可读性。至于数组_agg和json,这是获取我的信息并处理它们所必需的。我看不出这有什么问题。从我对你的问题的一点了解来看,你的问题似乎是你的连接在成倍地增加行(正如它们应该的那样),而你在整个集合上聚合。相反,您可能希望的是独立地运行聚合,然后加入。如果是这样的话(事实上,即使不是这样),您最好先找到所需的行,然后在单独的查询中,根据后者获取一些聚合。>>下面是我的查询。。。显示4列(id、姓名、奖金、技能),但结果显示5列(id、姓名、表3、表4、表2项)。然后,“工作”查询显示3。我搞不懂你在比较什么。