为什么where子句中的random()函数导致查询返回多于或少于一行?

时间:2014-07-30 09:49:47

标签: sql postgresql-9.3

这个查询怎么可能返回多行?它怎么能返回零行?

WITH cte(k,v) AS (VALUES (0,'A'), (1,'B'), (2,'C'))
SELECT * FROM cte WHERE k=round(random()*2);

有时候会返回一行,有时是两行,有时甚至是三行。但是如果random()函数返回一个值,那么该值可以匹配表中不超过一行,对吧?如果我将它乘以2并舍入为整数,则返回的值必须是012,因此必须恰好匹配一行,右?

如果我将random()调用放在这样的子查询中:

WITH cte(k,v) AS (VALUES (0,'A'), (1,'B'), (2,'C'))
SELECT * FROM cte WHERE k=(select round(random()*2));

然后它只返回一行,就像没有子查询一样。

和查询

SELECT round(random()*2);

只返回一行,其中一列的值为012,所以我不明白它是如何匹配除了行中的一行之外的任何一行cte表。然而,在上面的第一个查询中,有时似乎匹配多于或少于一行。这是怎么回事?

2 个答案:

答案 0 :(得分:3)

正如其他人所说,每行都会调用random()

如果你想要一个随机行,你可以使用ORDER BY random()子句然后LIMIT结果到一行,就像这样(未经测试):

WITH cte(k,v) AS (VALUES (0,'A'), (1,'B'), (2,'C')) SELECT * FROM cte ORDER BY random() LIMIT 1;

答案 1 :(得分:2)

据推测,您的源数据中的每个行都会调用random(),而不是一次(就像您假设的那样)。

因此,源数据中的每一行都有33%的可能性被返回。