如何在PostgreSQL中使用SELECT DISTINCT和RANDOM()函数?

egdjgwm8  于 2023-05-17  发布在  PostgreSQL
关注(0)|答案(5)|浏览(249)

我试图运行一个SQL查询来获取四个随机项。由于表product_filterproduct中有多个元组,我必须在SELECT中使用DISTINCT,所以我得到了这个错误:

对于SELECT DISTINCT,ORDER BY表达式必须出现在选择列表中

但是如果我把RANDOM()放在我的SELECT中,它将避免DISTINCT的结果。
有人知道如何使用DISTINCTRANDOM()函数吗?下面是我的疑问。

SELECT DISTINCT
    p.id, 
    p.title
FROM
    product_filter pf
    JOIN product p ON pf.cod_product = p.cod
    JOIN filters f ON pf.cod_filter = f.cod
WHERE
    p.visible = TRUE
LIMIT 4
ORDER BY RANDOM();
nzkunb0c

nzkunb0c1#

你要么做一个子查询

SELECT * FROM (
    SELECT DISTINCT p.cod, p.title ... JOIN... WHERE
    ) ORDER BY RANDOM() LIMIT 4;

或者你尝试对这些相同的字段进行分组:

SELECT p.cod, p.title, MIN(RANDOM()) AS o FROM ... JOIN ...
    WHERE ... GROUP BY p.cod, p.title ORDER BY o LIMIT 4;

这两个表达式中哪一个的计算速度更快取决于表结构和索引;在cod和title上建立适当的索引,子查询版本将运行得更快(cod和title将从索引基数信息中获取,并且cod是JOIN所需的唯一键,因此如果您按title,cod和visible(在WHERE中使用)进行索引,则很可能根本不会访问物理表。
我不确定第二种表达方式是否也会发生这种情况。

uidvcgyl

uidvcgyl2#

简化查询以避免先验问题:

SELECT p.cod, p.title
FROM   product p
WHERE  p.visible
AND    EXISTS (
    SELECT 1
    FROM   product_filter pf
    JOIN   filters f ON f.cod = pf.cod_filter
    WHERE  pf.cod_product = p.cod
    )
ORDER  BY random()
LIMIT  4;

结果中只有表product中的列,其他表只检查是否存在匹配行。对于这种情况,EXISTS表达式可能是最快和最简单的。它不会将基表product中的行相乘,因此您不需要再次使用DISTINCT删除它们。
LIMIT必须最后出现,在ORDER BY之后。
我将WHERE p.visible = 't'简化为WHERE p.visible,同样的事情,只是boolean列更简单。

bkhjykvo

bkhjykvo3#

使用子查询。不要忘记表别名tLIMITORDER BY之后。

SELECT *
    FROM (SELECT DISTINCT a, b, c
          FROM datatable WHERE a = 'hello'
         ) t
    ORDER BY random()
    LIMIT 10;
zpf6vheq

zpf6vheq4#

我想你需要一个子查询:

select *
from (select DISTINCT p.cod, p.title
      from product_filter pf  join
           product p
           on pf.cod_product = p.cod
      where p.visible = 't'
     ) t
LIMIT 4
order by RANDOM()

首先计算不同的值,然后计算极限。
请注意,这确实会影响性能,因为在选择所需内容之前,此查询会对所有内容执行不同的操作。这是否重要取决于表的大小以及如何使用查询。

ccrfmcuu

ccrfmcuu5#

SELECT DISTINCT U.* FROM
(

    SELECT p.cod, p.title FROM product__filter pf

      JOIN product p on pf.cod_product = p.cod
      JOIN filters f on pf.cod_filter = f.cod

    WHERE p.visible = 't' 

    ORDER BY RANDOM()

) AS U

LIMIT 4

这首先是随机的,然后是极限。

相关问题