admin

PostgreSQL-选择条件成立的distinct(column1,column2)

sql

我有下表和一些示例记录:

  id  | attr1_id | attr2_id |      user_id      | rating_id |
------+----------+----------+-------------------+-----------+
 1    |      188 |      201 | user_1@domain.com |         3 |
 2    |      193 |      201 | user_2@domain.com |         2 |
 3    |      193 |      201 | user_2@domain.com |         1 |
 4    |      194 |      201 | user_2@domain.com |         1 |
 5    |      194 |      201 | user_1@domain.com |         1 |
 6    |      192 |      201 | user_2@domain.com |         1 |

的组合(attr1_idattr2_iduser_id)的UNIQUE,这意味着每个用户只能创建与特定的一对属性id的一个记录。

我的目标是选择(attr1_id,attr2_id)的所有不同组合rating_id = 1,但是,仅选择和的每个组合,attr1_id并且仅选择attr2_id一次,并且仅在不存在(由其他用户使用)具有rating_id > 1并引用相同attr1_id和的任何其他行的情况下。attr2_id。请注意,组合attr1_idattr2_id可切换左右,所以给这两个记录:

  id  | attr1_id | attr2_id |      user_id       | rating_id | override_comment
------+----------+----------+--------------------+-----------+------------------
  20  |       5  |       2  | user_1@domain.com  |         3 |
------+----------+----------+--------------------+-----------+------------------
  21  |       2  |       5  | user_2@domain.com  |         1 |

不应计算任何行,因为这些行指的是的相同组合,attr_ids其中之一具有rating_id > 1

但是,如果存在这两行:

  id  | attr1_id | attr2_id |      user_id       | rating_id | override_comment
------+----------+----------+--------------------+-----------+------------------
  20  |       5  |       2  | user_1@domain.com  |         1 |
------+----------+----------+--------------------+-----------+------------------
  21  |       2  |       5  | user_2@domain.com  |         1 |
------+----------+----------+--------------------+-----------+------------------
  22  |       2  |       5  | user_3@domain.com  |         1 |

所有行应该只能算作一个,因为他们都有着相同的组合attr1_id,并attr2_id和所有有rating_id = 1

另外,我将省略一些联接表列的联接和过滤,但是我还是想提到它。

SQL Fiddle现在对我不起作用,但是我已经
从兼容性表中上传了一些示例数据。

到目前为止,我的查询是这样的:

SELECT distinct(a1, a2),
       a1,
       a2
FROM
  ( SELECT c.*,
           least(attr1_id, attr2_id) AS a1,
           greatest(attr1_id, attr2_id) AS a2
   FROM compatibility c
   JOIN attribute a ON c.attr1_id = a.id
   JOIN PARAMETER pa ON a.parameter_id = pa.id
   JOIN problem p ON pa.problem_id = p.id
   WHERE p.id = 1
   GROUP BY 1,
            2 HAVING NOT bool_or(rating_id > 1)) s;

在样本中,总共有144个评分。每个用户都创建了7个具有的rating_id > 1评分,在这14个评分中,有2个引用了同一组(attr1_idattr2_id)。因此,我要寻找的号码将是(77-12) = 65。但是,这里的结果似乎是77-2 = 75。因此,只有存在两个具有相同属性ID的等级的行才被丢弃。


阅读 146

收藏
2021-06-07

共1个答案

admin

我认为这符合您的描述:

select least(attr1_id, attr2_id) as attr1, greatest(attr1_id, attr2_id) as attr2
from table t
group by least(attr1_id, attr2_id), greatest(attr1_id, attr2_id) 
having bool_and(rating_d = 1) ;

我不理解查询中的其他表,因为您从拥有所需所有内容的单个表开始。

2021-06-07