我有三个表,A
B
和C
。对于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 |
因此,对于A
和B
的任意组合,都需要在C
中查找一个值。我希望这一切都有道理。
实际上,A x B
的大小对于数据库来说可能相对较小,但是太大而无法手动填充测试数据。因此,我想随机填充C
的表格,以了解A
和B
中可能存在的任何数据。
我对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));
}
}
答案 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;
(您不要将VALUES
与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;
答案 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