SQL连接表作为JSON数据

问题描述 投票:0回答:1

我正在尝试加入评论和喜欢的产品,但似乎,由于某种原因,“评论”列的输出重复的另一个外国表的长度,喜欢,“评论”的输出长度是

amount of likes * amount of reviews

我不知道为什么会这样

我想要的输出是“评论”列包含一个JSON数据数组,这样一个数组就等于相关评论的一行

制品

Title        Image
----------------------
Photo        photo.jpg
Book         book.jpg
Table        table.jpg

用户

Username
--------
Admin
John
Jane

产品喜欢

product_id    user_id
---------------------
1             1
1             2
2             1
2             3

产品评论

product_id    user_id    review
-------------------------------------
1             1          Great Product!
1             2          Looks Great
2             1          Could be better

这是查询

SELECT "products".*, 
array_to_json(array_agg("product_review".*)) as reviews,
EXISTS(SELECT * FROM product_like lk
JOIN users u ON u.id = "lk"."user_id" WHERE u.id = 4
AND "lk"."product_id" = products.id) AS liked,
COUNT("product_like"."product_id") AS totalLikes from "products"
LEFT JOIN "product_review" on "product_review"."product_id" = "products"."id" 
LEFT JOIN "product_like" on "product_like"."product_id" = "products"."id" 
group by "products"."id"

查询以创建架构和插入数据

CREATE TABLE products
    (id SERIAL, title varchar(50), image varchar(50), PRIMARY KEY(id))
;

CREATE TABLE users
    (id SERIAL, username varchar(50), PRIMARY KEY(id))
;

INSERT INTO products
    (title,image)
VALUES
    ('Photo', 'photo.jpg'),    
    ('Book', 'book.jpg'),
    ('Table', 'table.jpg')
;

INSERT INTO users
    (username)
VALUES
    ('Admin'),    
    ('John'),
    ('Jane')
;






CREATE TABLE product_review
    (id SERIAL, product_id int NOT NULL, user_id int NOT NULL, review varchar(50), PRIMARY KEY(id), FOREIGN KEY (product_id) references products, FOREIGN KEY (user_id) references users)
;

INSERT INTO product_review
    (product_id, user_id, review)
VALUES
    (1, 1, 'Great Product!'),
    (1, 2, 'Looks Great'),
    (2, 1, 'Could be better')
;



CREATE TABLE product_like
    (id SERIAL, product_id int NOT NULL, user_id int NOT NULL, PRIMARY KEY(id), FOREIGN KEY (product_id) references products, FOREIGN KEY (user_id) references users)
;

INSERT INTO product_like
    (product_id, user_id)
VALUES
    (1, 1),
    (1, 2),
    (2, 1),
    (2, 3)

摆弄架构和查询:http://sqlfiddle.com/#!15/dff2c/1

提前致谢

sql postgresql join
1个回答
1
投票

您获得多个结果的原因是因为product_idproduct_review以及product_like之间的一对多关系导致聚合之前的行重复。要解决此问题,您需要在子查询中执行这些表的聚合,并加入派生表:

SELECT "products".*, 
"pr"."reviews",
EXISTS(SELECT * FROM product_like lk
JOIN users u ON u.id = "lk"."user_id" WHERE u.id = 4
AND "lk"."product_id" = products.id) AS liked,
COALESCE("pl"."totalLikes", 0) AS totalLikes
FROM "products"
LEFT JOIN (SELECT product_id, array_to_json(array_agg("product_review".*)) AS reviews
           FROM "product_review"
           GROUP BY product_id) "pr" on "pr"."product_id" = "products"."id" 
LEFT JOIN (SELECT product_id, COUNT(*) AS "totalLikes"
           FROM "product_like"
           GROUP BY product_id) "pl" on "pl"."product_id" = "products"."id" 

输出:

id  title   image       reviews                                                                                                                     liked   totallikes
1   Photo   photo.jpg   [{"id":1,"product_id":1,"user_id":1,"review":"Great Product!"},{"id":2,"product_id":1,"user_id":2,"review":"Looks Great"}]  f       2
2   Book    book.jpg    [{"id":3,"product_id":2,"user_id":1,"review":"Could be better"}]                                                            f       2
3   Table   table.jpg                                                                                                                               f       0

Demo on dbfiddle

© www.soinside.com 2019 - 2024. All rights reserved.