我看到了一些奇怪的东西,我想不通了.我有一个postgres函数:

-- Random int between low and high
CREATE OR REPLACE FUNCTION rand_between(low INTEGER, high INTEGER)
  RETURNS INTEGER AS
$$
BEGIN
  RETURN floor(random() * (high - low + 1) + low);
END;
$$ language 'plpgsql' STRICT;

就其本身而言,它的效果很好:

SELECT rand_between(1, 512);

rand_between
------------
42

我有一个包含唯一整数和文本值的小表:

CREATE TABLE IF NOT EXISTS random_names
(
  id    INTEGER NOT NULL UNIQUE,
  value text NOT NULL
);

insert into random_names (id, value)
values
(1, 'AARON'),
(2, 'ABEL'),
(3, 'ADAM'),
(4, 'ALAN'),
(5, 'ALEX'),
(6, 'ALLAN'),
(7, 'ALLEN'),
(8, 'ALTON'),
(9, 'ALVIN'),
(10, 'AMOS');

现在,当我在WHERE子句的另一个查询中使用它时,我有时没有甚至多个记录:

SELECT value FROM random_names WHERE id = rand_between(1, 10);

为什么我有时会得到一条空记录或多条记录?我不明白,我希望这个数据集只有一个结果.我不明白,谢谢你的帮助.

推荐答案

您在WHERE子句中遇到的rand_between函数的问题是因为表中的每一行都多次调用该函数.

在SQL中,当在WHERE子句中使用函数时,将对与查询的其他条件匹配的每一行执行该函数.对于random_names表中的每一行,分别调用rand_between(1, 10)函数,在1 and 10之间生成一个新的随机数.因此,您可能会为每一行获得不同的数字,从而导致意外行为.

您可以修改查询,生成一个介于1 and 10之间的随机数,然后在WHERE子句中使用它.下面是使用子查询的示例:

SELECT value
FROM random_names
WHERE id = (SELECT rand_between(1, 10));

通过使用这种方法,您应该一致地根据生成的随机数获得一个结果,而不是一个都没有或多个记录.

Sql相关问答推荐

在SQL Server中使用LEFT连接包含特定记录

基于多个字段删除Access中的重复记录,同时保留最低优先级

Oracle分层查询-两条路径在末尾合并为一条

Oracle PL/SQL:解决DBMS输出大小限制的问题

按连续相等值分组排序

按用户和时间列出的SQL Group考勤列表

更正用于判断错误组合的SQL

SQL仅返回第一个字母在A-Z之间的值

使用CTE在SNOWFLAKE中创建临时表

Postgresql - WHERE 中的 MAX 标准 - 初学者问题

显示所有组并计算给定组中的项目(包括 0 个结果)

PostgreSQL-用第一个非空填充以前的值

如何根据共同列值从两个表中包含列,但只包含左表中的行

MariaDB非常简单的MATCHAGAINST查询不使用FULLTEXT索引吗?

PostgreSQL如何将Unix纪元时间戳转换为日期时间并进行拼接

使用给定的变量对在循环中执行更新语句

在 MS Access 中连接相关记录

条件前置值

如何使用 pg-promise 创建要在复杂的 sql 查询中使用的 VALUES 列表?

snowfalke 会在 Select 运行时锁定表吗?