1

我有三张桌子,A B并且C。对于 in 中的每个条目A x B(其中 x 是笛卡尔积或交叉连接),在 中都有一个条目C

换句话说,如果有 2 个条目 for和 3 个 for ,表格 forC可能如下所示:AB

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

A因此,对于和的任何组合B,都有一个要在 中查找的值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));
    }
}
4

3 回答 3

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;

(你不使用VALUESwith INSERT/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;
于 2012-07-23T14:55:13.493 回答
2
select A_id,B_Id, abs(checksum(newid()))%101 as C_val from A cross join B

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

于 2012-07-23T14:56:54.813 回答
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 。来源

于 2012-07-23T14:55:53.717 回答