使用随机值填充“查找表”

时间:2012-07-23 14:48:59

标签: sql sql-server

我有三个表,A BC。对于A x B中的每个条目(其中x是笛卡尔积或交叉连接),C中都有一个条目。

换句话说,如果C有2个条目,A有3个条目,则B的表格可能如下所示:

| A_ID | B_ID | C_Val |
----------------------|
|  1   |  1   |  100  |
|  1   |  2   |  56   |
|  1   |  3   |  19   |
|  2   |  1   |  67   |   
|  2   |  2   |  0    |
|  2   |  3   |  99   |

因此,对于AB的任意组合,都需要在C中查找一个值。我希望这一切都有道理。

实际上,A x B的大小对于数据库来说可能相对较小,但是太大而无法手动填充测试数据。因此,我想随机填充C的表格,以了解AB中可能存在的任何数据。

我对SQL的了解非常基础。我到目前为止所确定的是将笛卡尔积作为内部查询,如下所示:

(SELECT B.B_ID, C.C_ID
 FROM B CROSS JOIN C)

然后我想说下面的话:

INSERT INTO A(B_ID, C_ID, A_Val) VALUES
    (SELECT B.B_ID, C.C_ID, FLOOR(RAND() * 100)
     FROM B CROSS JOIN C)

毫不奇怪,这不起作用。我不认为它是有效的语法,可以像这样生成一个列,也不会尝试将整个表作为值插入。

我怎样才能将这个普通的编程伪代码转换为正确的SQL?

foreach(A_ID in A){
    foreach(B_ID in B){
        C.insert(A_ID, B_ID, Rand(100));
    }
}

3 个答案:

答案 0 :(得分:3)

语法问题是因为:

INSERT INTO A(B_ID, C_ID, A_Val) VALUES
  (SELECT B.B_ID, C.C_ID, FLOOR(RAND() * 100)
   FROM B CROSS JOIN C)

应该是:

INSERT INTO A(B_ID, C_ID, A_Val) 
  SELECT B.B_ID, C.C_ID, FLOOR(RAND() * 100)
   FROM B CROSS JOIN C;

(您不要将VALUESINSERT/SELECT一起使用。)

但是,您仍然会遇到不对每行评估RAND()的问题;它对每一行都有相同的值。假设B_ID和C_ID的组合是唯一的,您可以使用以下内容:

INSERT INTO A(B_ID, C_ID, A_Val) 
  SELECT B.B_ID, C.C_ID, ABS(CHEKSUM(RAND(B.B_ID*C.C_ID))) % 100
   FROM B CROSS JOIN C;

答案 1 :(得分:2)

select A_id,B_Id, abs(checksum(newid()))%101 as C_val from A cross join B

这将为您提供0到100范围内的不同值

答案 2 :(得分:0)

使用CTE

  With cte as
  (SELECT B.B_ID, C.C_ID, ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) as A_Val
    FROM B CROSS JOIN C) 
  Insert into Table(B_ID, C_ID, A_Val)
  Select B_ID,C_ID,A_Val from cte

由于rand生成相同的数字,因此您可以使用NEWID。Source