sql >> データベース >  >> RDS >> Sqlserver

SQL ServerでRAND()を決定論的にする方法

    RAND() SQL Serverの関数は、0から1までの疑似ランダム浮動小数点値を返します。

    この関数は、呼び出される方法に応じて、決定論的または非決定論的になります。

    決定論的関数は、指定された入力値のセットとデータベースの同じ状態に対して常に同じ結果を返します。非決定論的関数は、データベースの状態が同じままであっても、同じ入力値のセットで異なる結果を返す場合があります。

    RAND() 関数は2つの方法で呼び出すことができます。シードあり、シードなし。シードなしで呼び出すと、決定論的ではありません。シードで呼び出すと、決定論的です。

    つまり、指定されたシード値に対して、返される結果は常に同じです。

    ただし、落とし穴があります。RAND()を呼び出すこともあります。 シードなし 決定論的。これについては以下で説明します。

    構文

    まず、構文は次のとおりです。

    RAND ( [ seed ] )
    

    角かっこは、シード引数がオプションであることを意味します。

    例1-シードなし

    ここでは、RAND()を呼び出します シードなしで5回。

    SELECT RAND() AS [No Seed]
    UNION ALL
    SELECT RAND()
    UNION ALL
    SELECT RAND()
    UNION ALL
    SELECT RAND()
    UNION ALL
    SELECT RAND()
    

    結果:

    +-------------------+
    | No Seed           |
    |-------------------|
    | 0.2054995913191   |
    | 0.821844434880088 |
    | 0.4204955495022   |
    | 0.286702661673299 |
    | 0.394385747185196 |
    +-------------------+
    

    各行には異なる値があります。

    例2–シードあり

    ここでは、各関数呼び出しに同じシードを追加することを除いて、同じクエリを実行します。

    SELECT RAND(100) AS [With Seed]
    UNION ALL
    SELECT RAND(100)
    UNION ALL
    SELECT RAND(100)
    UNION ALL
    SELECT RAND(100)
    UNION ALL
    SELECT RAND(100)
    

    結果:

    +-------------------+
    | With Seed         |
    |-------------------|
    | 0.715436657367485 |
    | 0.715436657367485 |
    | 0.715436657367485 |
    | 0.715436657367485 |
    | 0.715436657367485 |
    +-------------------+
    

    この場合、すべての行の値は同じです。

    例3–同じクエリでシードとシードなしを組み合わせる(複数のRAND()呼び出し)

    RAND()を呼び出すときは注意が必要です 同じ接続で複数回。 RAND()を呼び出す場合 指定されたシード値を使用して、RAND()の後続のすべての呼び出し シードされたRAND()に基づいて結果を生成します 電話。

    そのため、誤ってRAND()を実行していると思われる可能性があります。 実際にはそうではないのに、非決定論的に。

    実例を示します。

    SELECT 
      RAND(100) AS [With Seed], 
      RAND() AS [No Seed], 
      RAND() AS [No Seed]
    UNION ALL
    SELECT 
      RAND(100) AS [With Seed], 
      RAND() AS [No Seed], 
      RAND() AS [No Seed]
    UNION ALL
    SELECT 
      RAND(100) AS [With Seed], 
      RAND() AS [No Seed], 
      RAND() AS [No Seed];
    

    結果:

    +-------------------+------------------+--------------------+
    | With Seed         | No Seed          | No Seed            |
    |-------------------+------------------+--------------------|
    | 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 |
    | 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 |
    | 0.715436657367485 | 0.28463380767982 | 0.0131039082850364 |
    +-------------------+------------------+--------------------+
    

    結果の値は列によって異なりますが、各「シードなし」の呼び出しは実際には「シードあり」の呼び出しに基づいているため、決定論的です。

    関数呼び出しをシャッフルすると、次のようになります。

    SELECT 
      RAND() AS [No Seed], 
      RAND() AS [No Seed],
      RAND(100) AS [With Seed]
    UNION ALL
    SELECT 
      RAND() AS [No Seed], 
      RAND() AS [No Seed],
      RAND(100) AS [With Seed]
    UNION ALL
    SELECT 
      RAND() AS [No Seed], 
      RAND() AS [No Seed],
      RAND(100) AS [With Seed];
    

    結果:

    +------------------+--------------------+-------------------+
    | No Seed          | No Seed            | With Seed         |
    |------------------+--------------------+-------------------|
    | 0.28769876521071 | 0.100505471175005  | 0.715436657367485 |
    | 0.28463380767982 | 0.0131039082850364 | 0.715436657367485 |
    | 0.28463380767982 | 0.0131039082850364 | 0.715436657367485 |
    +------------------+--------------------+-------------------+
    

    1. R12/R12.2のOracleForms

    2. SQLServerのMaven依存関係の設定

    3. 単一のクエリでの複数のselectステートメント

    4. SQL Server(T-SQL)でデータベースの照合を設定する方法