【问题标题】:Generate a random number in the range 1 - 10生成 1 - 10 范围内的随机数
【发布时间】:2010-11-26 21:29:43
【问题描述】:

由于我在this question 中处理的测试查询方法没有成功,我现在正在尝试其他方法。有没有办法告诉 pg 的 random() 函数只获取 1 到 10 之间的数字?

【问题讨论】:

    标签: sql postgresql random


    【解决方案1】:

    如果用 1 到 10 之间的数字表示任何 >= 1 且

    select random() * 9 + 1
    

    这可以通过以下方式轻松测试:

    # select min(i), max(i) from (
        select random() * 9 + 1 as i from generate_series(1,1000000)
    ) q;
           min       |       max
    -----------------+------------------
     1.0000083274208 | 9.99999571684748
    (1 row)
    

    如果你想要整数,即 >= 1 和

    select trunc(random() * 9 + 1)
    

    再一次,简单的测试:

    # select min(i), max(i) from (
        select trunc(random() * 9 + 1) as i from generate_series(1,1000000)
    ) q;
     min | max
    -----+-----
       1 |   9
    (1 row)
    

    【讨论】:

    • 从事件 e 中选择日期(e.created_at) + (trunc(random() * 20));结果:错误:运算符不存在:日期+双精度trunc真的返回整数吗?
    • trunc() 返回与输入相同的数据类型(如手册中所述)。您需要将结果转换为整数:trunc(random() * 20)::int
    • 我想知道至少在理论上 random() 是否有可能返回一个值 inexact nature of the double precision type,当乘以 9 时将 >=9?在实践中,即使有可能,由于 15 位左右的精度,这当然是不可能的。
    • 我在玩 width_bucket(random(), 0, 1, 10) 作为替代
    • 看起来像 my fears were groundless 虽然我承认我根本不懂数学:-)
    【解决方案2】:

    为了总结和简化,您可以使用:

    -- 0 - 9
    select floor(random() * 10);
    -- 0 - 10
    SELECT floor(random() * (10 + 1));
    -- 1 - 10
    SELECT ceil(random() * 10);
    

    你可以像@user80168提到的那样测试这个

    -- 0 - 9
    SELECT min(i), max(i) FROM (SELECT floor(random() * 10) AS i FROM generate_series(0, 100000)) q;
    -- 0 - 10
    SELECT min(i), max(i) FROM (SELECT floor(random() * (10 + 1)) AS i FROM generate_series(0, 100000)) q;
    -- 1 - 10
    SELECT min(i), max(i) FROM (SELECT ceil(random() * 10) AS i FROM generate_series(0, 100000)) q;
    

    【讨论】:

    • docs say“0.0 ceil(random() * 10) 导致 0 的可能性——我会坚持使用 floor
    • 我同意@JackDouglas,所以对于范围 1 - 10,它应该是 SELECT floor(random() * 10 + 1);
    【解决方案3】:

    如果您使用的是 SQL Server,那么获取整数的正确方法是

    SELECT Cast(RAND()*(b-a)+a as int);
    

    在哪里

    • 'b'是上限
    • 'a' 是下限

    【讨论】:

    • 这里要小心,如果你把你的下限设为1,上限设为10,你只会得到1->9的数字。其他答案似乎假设介于 1 和 10 之间意味着 1->9 ......我建议如果“介于”不包括上限,它也应该排除下限(即 2->9)。 SELECT Cast(RAND()*((b+1)-a)+a as int);
    • 该问题已明确标记为 PostgreSQL 问题。
    【解决方案4】:

    (trunc(random() * 10) % 10) + 1

    【讨论】:

    • 错误:运算符不存在:双精度百分比整数
    • 为什么还要使用模数?这个逻辑没有意义。如果你得到任何“包装”,你就不会得到平等的分配,如果你没有得到,那么你就不需要它。
    【解决方案5】:

    hythlodayr 答案的正确版本。

    -- ERROR:  operator does not exist: double precision % integer
    -- LINE 1: select (trunc(random() * 10) % 10) + 1
    

    trunc 的输出必须转换为INTEGER。但是没有trunc也可以。所以结果很简单。

    select (random() * 9)::INTEGER + 1
    

    在 [1, 10] 范围内生成 INTEGER 输出,即包括 1 和 10。

    对于任何数字(浮点数),请参阅 user80168 的答案。即不要将其转换为INTEGER

    【讨论】:

      【解决方案6】:

      其实我不知道你想要这个。

      试试这个

      INSERT INTO my_table (my_column)
      SELECT
          (random() * 10) + 1
      ;
      

      【讨论】:

        【解决方案7】:

        此存储过程将 rand 数插入表中。注意,它插入了无穷无尽的数字。当你得到足够的数字时停止执行它。

        为光标创建一个表:

        CREATE TABLE [dbo].[SearchIndex](
        [ID] [int] IDENTITY(1,1) NOT NULL,
        [Cursor] [nvarchar](255) NULL) 
        

        创建一个表格来包含您的数字:

        CREATE TABLE [dbo].[ID](
        [IDN] [int] IDENTITY(1,1) NOT NULL,
        [ID] [int] NULL)
        

        插入脚本:

        INSERT INTO [SearchIndex]([Cursor])  SELECT N'INSERT INTO ID  SELECT   FLOOR(rand() * 9 + 1)  SELECT COUNT (ID) FROM ID
        

        创建和执行程序:

        CREATE PROCEDURE [dbo].[RandNumbers] AS
        BEGIN
        Declare  CURSE  CURSOR  FOR (SELECT  [Cursor] FROM [dbo].[SearchIndex]  WHERE [Cursor] IS NOT NULL)
        DECLARE @RandNoSscript NVARCHAR (250)
        OPEN CURSE
        FETCH NEXT FROM CURSE
        INTO @RandNoSscript 
        WHILE @@FETCH_STATUS IS NOT NULL 
        BEGIN
        Print @RandNoSscript
        EXEC SP_EXECUTESQL @RandNoSscript;  
         END
         END
        GO
        

        填满你的桌子:

        EXEC RandNumbers
        

        【讨论】:

        • 问题是关于 Postgres,而不是 SQL Server
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-12-24
        • 1970-01-01
        • 2019-04-28
        • 1970-01-01
        • 1970-01-01
        • 2013-11-19
        • 2011-03-01
        相关资源
        最近更新 更多