Postgresql离开了连接,没有重复

时间:2014-05-08 13:05:16

标签: postgresql left-join

数据库结构:

CREATE TABLE page
(
        id serial primary key,
        title VARCHAR(40) not null
);

CREATE TABLE page_rating
(
    id serial primary key,
    page_id INTEGER,
    rating_type INTEGER,
    rating INTEGER
);

CREATE TABLE user_history
(
    id serial primary key,
    page_id INTEGER
)

数据:

INSERT INTO page (id,title) VALUES(1,'Page #1');
INSERT INTO page (id,title) VALUES(2,'Page #2');
INSERT INTO page (id,title) VALUES(3,'Page #3');
INSERT INTO page (id,title) VALUES(4,'Page #4');
INSERT INTO page (id,title) VALUES(5,'Page #5');


INSERT INTO page_rating VALUES (1,1,60,100);
INSERT INTO page_rating VALUES (2,1,99,140);
INSERT INTO page_rating VALUES (3,1,58,120);
INSERT INTO page_rating VALUES (4,1,70,110);


INSERT INTO page_rating VALUES (5,2,60,50);
INSERT INTO page_rating VALUES (6,2,99,60);
INSERT INTO page_rating VALUES (7,2,58,90);
INSERT INTO page_rating VALUES (8,2,70,140);

目的 - 在表格中选择rating_type的唯一值" page"按" rating_page.rating"排序。并从结果中排除表user_history

我的查询:

SELECT DISTINCT ON(pr.rating_type) p.*,pr.rating,pr.rating_type FROM page as p
    LEFT JOIN page_rating as pr ON p.id = pr.page_id
    LEFT JOIN user_history uh ON uh.page_id = p.id 
    WHERE 
        pr.rating_type IN (60, 99, 58, 45, 73, 97, 55, 59, 70, 43, 74, 97, 64, 71, 46) 
        AND uh.page_id IS NULL 

    ORDER BY pr.rating_type,pr.rating DESC

结果:

ID  TITLE      RATING RATING_TYPE   
1  "Page #1"   120    58
1  "Page #1"   100    60
2  "Page #2"   140    70
1  "Page #1"   140    99

重复值(理想:

ID  TITLE      RATING RATING_TYPE   
1  "Page #1"   120    58
1  "Page #2"   50     60

寻求帮助!

1 个答案:

答案 0 :(得分:1)

您几乎肯定需要在“page_rating”表中的{page_id,rating_type}上使用UNIQUE约束。您还缺少每个必需的外键约束。 “user_history”上的主键也是可疑的。

  

目的 - 在表“page”中为rating_type选择唯一值   按“rating_page.rating”排序。

您可以为rating_type选择不同的值,而无需引用任何其他表。而你应该,起初。我们来看看数据。

select page_id, rating_type, rating
from page_rating
order by page_id, rating_type;
page_id rating_type  rating
--
1       58           120 *
1       60           100
1       70           110
1       99           140
2       58            90
2       60            50 *
2       70           140
2       99            60

您似乎想要每页一行_id。这些行在上表中标有星号。我们怎样才能获得这两行?

这些行对rating_type具有不同的值,因此我们不能在WHERE子句中使用rating_type。对于rating_type的两个值,rating中的值既不是最大值也不是min,因此我们不能将GROUP BY与max()或min()一起使用。并且我们不能将GROUP BY与聚合函数一起使用,因为您希望将“rating”的未聚合值用于“rating_type”的任意值。

因此,根据您告诉我们的内容, only 获取所需结果集的方法是在WHERE子句中指定rating_type和page_id。

select page_id, rating_type, rating
from page_rating
where (page_id = 1 and rating_type = 58)
   or (page_id = 2 and rating_type = 60)
order by page_id, rating_type;
page_id rating_type  rating
--
1       58           120 
2       60            50 

我不打算继续加入,因为我100%确信你真的想要这样做。