当前位置: 首页 > 面试题库 >

PostgreSQL-为条件成立的行选择count(*)

公良安邦
2023-03-14
问题内容

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

  id  | attr1_id | attr2_id |      user_id      | rating_id | override_comment
------+----------+----------+-------------------+-----------+------------------
 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的一个记录。

我的目标是计算的行数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

到目前为止,我的方法是这样,但是它根本没有选择任何行。

SELECT *
FROM compatibility c
WHERE rating_id > 1
  AND NOT EXISTs
    (SELECT *
     FROM compatibility c2
     WHERE c.rating_id > 1
       AND (
             (c.attr1_id = c2.attr1_id) AND (c.attr2_id = c2.attr2_id)
             OR
             (c.attr1_id = c2.attr2_id) AND (c.attr2_id = c2.attr1_id)
           )
    )

我怎样才能做到这一点?


问题答案:

如果我理解正确,那么您想要的属性对始终为“ 1”。

这应该给您属性:

select least(attr1_id, attr2_id) as a1, greatest(attr1_id, attr2_id) as a2,
       min(rating_id) as minri, max(rating_id) as maxri
from compatibility c
group by least(attr1_id, attr2_id), greatest(attr1_id, attr2_id)
having min(rating_id) = 1 and max(rating_id) = 1;

要获得计数,只需将其用作子查询:

select count(*)
from (select least(attr1_id, attr2_id) as a1, greatest(attr1_id, attr2_id) as a2,
             min(rating_id) as minri, max(rating_id) as maxri
      from compatibility c
      group by least(attr1_id, attr2_id), greatest(attr1_id, attr2_id)
      having min(rating_id) = 1 and max(rating_id) = 1
     ) c


 类似资料:
  • 我在使用 PostgreSQL 的 ActiveRecord 中遇到了竞争条件,我正在读取一个值,然后递增它并插入一条新记录: 按比例,多个线程将同时读取并写入的相同值。将其封装在事务中并不能修复竞争条件,因为SELECT不会锁定表。我不能使用自动递增,因为不是唯一的,它只在给定特定的时才是唯一的。我看到3种可能的修复方法: > < li> 显式使用postgres锁(行级锁?) 使用唯一约束并在

  • 常常来说,一个play的结果经常取决于一个变量的值,事件(从远端系统得到事件),或者之前任务的结果.在有些情况下,这些变量的值也会取决于其他变量. 进而,可以建立多余的组基于这些主机是否符合某些条件来操控主机,Ansible 提供了很多不同选项,来控制执行流. 让我们详细看看这些都是啥. When 语句 有时候用户有可能需要某一个主机越过某一个特定的步骤.这个过程就可以简单的像在某一个特定版本的系

  • 问题内容: 我正在尝试将其编译。.我有一个带有firstname和lastname字段的表,并且我有一个字符串,例如“ Bob Jones”或“ Bob Michael Jones”等。 事实是,例如我姓鲍勃,姓迈克尔·琼斯 所以我想 但是它说未知列“ firstlast” ..有人可以帮助吗? 问题答案: 您提供的别名用于查询的输出-它们本身在查询中不可用。 您可以重复表达: 或包装查询

  • 问题内容: 如何在SQL(PostgreSQL)查询中选择20个随机行? 问题答案: SELECT column FROM table ORDER BY RANDOM() LIMIT 20

  • 我在这里发现了类似的问题:Postgres json键计数。 但是,它需要密钥的名称,这可以不使用密钥名称吗? 解决方案 在查询中使用函数: 如果有更好的方法来建模这个查询,请给出建议。谢了!

  • 问题内容: 我正在尝试将其编译。.我有一个带有firstname和lastname字段的表,并且我有一个字符串,例如“ Bob Jones”或“ Bob Michael Jones”等。 事实是,例如,我姓鲍勃,姓迈克尔·琼斯 所以我想 但是它说未知列“ firstlast” ..有人可以帮助吗? 问题答案: 您提供的别名用于查询的输出-它们本身在查询中不可用。 您可以重复以下表达式: 或包装查询