如何在PostgreSQL中正确循环表并输出到数组?

时间:2013-07-22 23:02:20

标签: sql node.js postgresql

这是一个数据库示例

table "Users"
fname | lname | id | email 
Joe   | smith | 1  | yadda@goo.com
Bob   | smith | 2  | bob@goo.com
Jane  | smith | 3  | jane@goo.com

table "Awards"
userId | award 
1      | bigaward
1      | smallaward
1      | thisaward
2      | thataward

table "Invites"
userId | invited
1      | true
3      | true

基本上,你如何在PostgreSQL中编写一个允许你创建这样的东西的查询:

[{
     fname:"Joe",
     lname:"Smith",
     id: 1,
     email: "yadda@goo.com",
     invited: true,
     awards: ["bigaward", "smallaward", "thisaward"]
 },
 {
     fname:"Jane",
     lname:"Smith",
     id: 3,
     email: "jane@goo.com",
     invited: true,
     awards: []
 }]

这是我想要做的......

SELECT users.fname, users.lname, users.id, users.email, invites.invited, awards.award(needs to be an array)
FROM users
JOIN awards on ....(unknown)
JOIN invites on invites.userid = users.id
WHERE invited = true

上面的数组将是所需的输出,只是无法弄清楚一个好的一次性查询。我尝试了PostgreSQL文档,但无济于事。我想我可能需要一个WITH语句?

先谢谢,Postgres大师!

PostgreSQL v.9.2

RhodiumToad在postgresql IRC上的回答:

SELECT users.fname, users.lname, .... array(select awards.award from awards where a.id = user.id) as awards
FROM users
JOIN invites on invites.userid = users.id
WHERE invited = true

array()然后通过它内部的查询......辉煌!

2 个答案:

答案 0 :(得分:1)

我认为它可以很简单:

SELECT u.fname, u.lname, u.id, u.email, i.invited, array_agg(a.award)
FROM   users u
JOIN   invites i ON i.userid = u.id AND i.invited
LEFT   JOIN awards a ON a.userid = u.id
GROUP  BY u.fname, u.lname, u.id, u.email, i.invited

您的JSON格式显示只会让它看起来更复杂。

使用基本的GROUP BY,包括所有不会聚合的列 - 将award留下,并在聚合函数array_agg()的帮助下将其聚合成数组。

LEFT JOIN很重要,所以不要在没有任何奖励的情况下排除用户。

请注意,我在示例中忽略了CaMeL-case拼写,以避免丑陋的双引号。

对于较大的表而言,这比<} correlated subqueries更加更快 - 就像在问题中添加的示例中所示。

->SQLfiddle demo

答案 1 :(得分:0)

您需要使用hasNext或forEach(或类似)方法来迭代数据库。在进行迭代时,可以将结果添加到数组中,然后将该数组编码为JSON。

我想我可能误解了你的问题。抱怨道歉