[英]How to use SELECT DISTINCT with RANDOM() function in PostgreSQL?
我正在尝试运行 SQL 查询以获取四个随机项目。 由于表product_filter
在product
有不止一个 touple 我必须在SELECT
使用DISTINCT
,所以我得到这个错误:
对于 SELECT DISTINCT,ORDER BY 表达式必须出现在选择列表中
但是如果我将RANDOM()
放在我的SELECT
,它将避免DISTINCT
结果。
有人知道如何将DISTINCT
与RANDOM()
函数一起使用吗? 下面是我有问题的查询。
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();
你要么做一个子查询
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 所需的唯一键,因此如果您按标题、cod 和可见(用于WHERE),很可能根本就不会访问物理表。
我不太确定这是否也会发生在第二个表达式中。
您可以简化查询以避免先验问题:
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'
简化为p.visible
,因为这应该是一个布尔列。
使用子查询。 不要忘记表别名t
。 LIMIT
在ORDER BY
。
SELECT *
FROM (SELECT DISTINCT a, b, c
FROM datatable WHERE a = 'hello'
) t
ORDER BY random()
LIMIT 10;
我认为你需要一个子查询:
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()
首先计算不同的值,然后进行限制。
请注意,这确实会影响性能,因为在选择您想要的内容之前,此查询会对所有内容进行不同的处理。 这是否重要取决于您的表的大小以及您如何使用查询。
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
这首先执行 RANDOM,然后执行 LIMIT。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.