SQL에서 열을 난수로 채우려면 어떻게 해야 합니까?모든 행에서 동일한 값을 얻을 수 있습니다.
UPDATE CattleProds
SET SheepTherapy=(ROUND((RAND()* 10000),0))
WHERE SheepTherapy IS NULL
그런 다음 SELECT를 실행하면 모든 행에서 랜덤 번호가 동일한 것을 알 수 있습니다.독특한 난수를 생성하는 방법을 알고 있나요?
대신rand()
,사용하다newid()
이 값은 결과의 각 행에 대해 다시 계산됩니다.일반적인 방법은 체크섬의 모듈로를 사용하는 것입니다.주의:checksum(newid())
-2,480,483,648을 생성하여 정수 오버플로를 발생시킬 수 있습니다.abs()
따라서 체크섬 반환값을 절대값으로 변환하기 전에 modulo를 사용해야 합니다.
UPDATE CattleProds
SET SheepTherapy = abs(checksum(NewId()) % 10000)
WHERE SheepTherapy IS NULL
그러면 0 ~ 9999 사이의 난수가 생성됩니다.
SQL Server 2008을 사용하는 경우
CRYPT_GEN_RANDOM(2) % 10000
어느 정도 간단한 것 같습니다(한 줄에 한 번씩 평가됨).newid
이하에 나타냅니다.)
DECLARE @foo TABLE (col1 FLOAT)
INSERT INTO @foo SELECT 1 UNION SELECT 2
UPDATE @foo
SET col1 = CRYPT_GEN_RANDOM(2) % 10000
SELECT * FROM @foo
반환(2개의 랜덤한 숫자가 다를 수 있음)
col1
----------------------
9693
8573
설명되지 않은 다운베이트를 심사숙고해 보면 생성되는 난수가 0~65535로 10,000으로 균등하게 나누어지지 않기 때문에 일부 숫자는 약간 초과될 수 있습니다.이를 회피하기 위해서는 60,000을 넘는 임의의 번호를 폐기하고 재귀적으로 호출하여 교환번호를 취득하는 스칼라 UDF로 랩하는 방법이 있습니다.
CREATE FUNCTION dbo.RandomNumber()
RETURNS INT
AS
BEGIN
DECLARE @Result INT
SET @Result = CRYPT_GEN_RANDOM(2)
RETURN CASE
WHEN @Result < 60000
OR @@NESTLEVEL = 32 THEN @Result % 10000
ELSE dbo.RandomNumber()
END
END
CHECSUM을 사용하는 것을 좋아하지만, 더 좋은 방법은 CHECSUM을 사용하는 것입니다.NEWID()
단순한 숫자를 만들기 위해 복잡한 수학 과정을 거치지 않아도 된다는 이유만으로 말이다.
ROUND( 1000 *RAND(convert(varbinary, newid())), 0)
를 교환할 수 있습니다.1000
어떤 수를 제한으로 설정하고 항상 플러스 기호를 사용하여 범위를 생성할 수 있습니다.100
그리고.200
, 다음과 같은 작업을 수행할 수 있습니다.
100 + ROUND( 100 *RAND(convert(varbinary, newid())), 0)
질의에 정리하기:
UPDATE CattleProds
SET SheepTherapy= ROUND( 1000 *RAND(convert(varbinary, newid())), 0)
WHERE SheepTherapy IS NULL
각각 100,000,000개의 행을 생성하여 RAND()에 대해 2개의 설정 기반의 랜덤화 메서드를 테스트했습니다.필드를 수평으로 조정하려면 0-1 사이의 플로트가 출력되어 LAND()를 모방합니다.코드의 대부분은 인프라스트럭처의 테스트이기 때문에 알고리즘을 다음과 같이 정리합니다.
-- Try #1 used
(CAST(CRYPT_GEN_RANDOM(8) AS BIGINT)%500000000000000000+500000000000000000.0)/1000000000000000000 AS Val
-- Try #2 used
RAND(Checksum(NewId()))
-- and to have a baseline to compare output with I used
RAND() -- this required executing 100000000 separate insert statements
CRYPT_GEN_RANDOM을 사용하는 것은 10^18 번호 집합에서 10^8 번호를 추출할 때 중복이 발생할 확률은 .0000001%에 불과하기 때문에 가장 랜덤한 방법입니다.IOW 우리는 중복된 것을 보지 말았어야 했고 이것은 아무것도 없었다!이 세트를 노트북으로 생성하는 데 44초가 걸렸습니다.
Cnt Pct
----- ----
1 100.000000 --No duplicates
SQL Server 실행 시간: CPU 시간 = 134795 ms, 경과 시간 = 39274 ms.
IF OBJECT_ID('tempdb..#T0') IS NOT NULL DROP TABLE #T0;
GO
WITH L0 AS (SELECT c FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS D(c)) -- 2^4
,L1 AS (SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B) -- 2^8
,L2 AS (SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B) -- 2^16
,L3 AS (SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B) -- 2^32
SELECT TOP 100000000 (CAST(CRYPT_GEN_RANDOM(8) AS BIGINT)%500000000000000000+500000000000000000.0)/1000000000000000000 AS Val
INTO #T0
FROM L3;
WITH x AS (
SELECT Val,COUNT(*) Cnt
FROM #T0
GROUP BY Val
)
SELECT x.Cnt,COUNT(*)/(SELECT COUNT(*)/100 FROM #T0) Pct
FROM X
GROUP BY x.Cnt;
거의 15배 적은 랜덤으로 이 방법은 1억 개의 숫자를 생성하는 데 23초밖에 걸리지 않아 두 배나 빠르지 않았습니다.
Cnt Pct
---- ----
1 95.450254 -- only 95% unique is absolutely horrible
2 02.222167 -- If this line were the only problem I'd say DON'T USE THIS!
3 00.034582
4 00.000409 -- 409 numbers appeared 4 times
5 00.000006 -- 6 numbers actually appeared 5 times
SQL Server 실행 시간: CPU 시간 = 77156 ms, 경과 시간 = 24613 ms.
IF OBJECT_ID('tempdb..#T1') IS NOT NULL DROP TABLE #T1;
GO
WITH L0 AS (SELECT c FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS D(c)) -- 2^4
,L1 AS (SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B) -- 2^8
,L2 AS (SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B) -- 2^16
,L3 AS (SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B) -- 2^32
SELECT TOP 100000000 RAND(Checksum(NewId())) AS Val
INTO #T1
FROM L3;
WITH x AS (
SELECT Val,COUNT(*) Cnt
FROM #T1
GROUP BY Val
)
SELECT x.Cnt,COUNT(*)*1.0/(SELECT COUNT(*)/100 FROM #T1) Pct
FROM X
GROUP BY x.Cnt;
RAND()만으로는 세트 기반 생성에는 사용할 수 없기 때문에 랜덤성을 비교하기 위한 기준선을 생성하는 데 6시간이 걸리고 적절한 수의 출력 행을 얻기 위해 여러 번 재시작해야 합니다.또한 랜덤성은 체크섬(newid)을 사용하여 각 행을 다시 설치하는 것보다 더 좋지만 아쉬운 점이 많은 것 같습니다.
Cnt Pct
---- ----
1 99.768020
2 00.115840
3 00.000100 -- at least there were comparitively few values returned 3 times
재시작으로 인해 실행 시간을 캡처할 수 없습니다.
IF OBJECT_ID('tempdb..#T2') IS NOT NULL DROP TABLE #T2;
GO
CREATE TABLE #T2 (Val FLOAT);
GO
SET NOCOUNT ON;
GO
INSERT INTO #T2(Val) VALUES(RAND());
GO 100000000
WITH x AS (
SELECT Val,COUNT(*) Cnt
FROM #T2
GROUP BY Val
)
SELECT x.Cnt,COUNT(*)*1.0/(SELECT COUNT(*)/100 FROM #T2) Pct
FROM X
GROUP BY x.Cnt;
require_once('db/connect.php');
//rand(1000000 , 9999999);
$products_query = "SELECT id FROM products";
$products_result = mysqli_query($conn, $products_query);
$products_row = mysqli_fetch_array($products_result);
$ids_array = [];
do
{
array_push($ids_array, $products_row['id']);
}
while($products_row = mysqli_fetch_array($products_result));
/*
echo '<pre>';
print_r($ids_array);
echo '</pre>';
*/
$row_counter = count($ids_array);
for ($i=0; $i < $row_counter; $i++)
{
$current_row = $ids_array[$i];
$rand = rand(1000000 , 9999999);
mysqli_query($conn , "UPDATE products SET code='$rand' WHERE id='$current_row'");
}
언급URL : https://stackoverflow.com/questions/5003028/how-can-i-fill-a-column-with-random-numbers-in-sql-i-get-the-same-value-in-ever
'programing' 카테고리의 다른 글
열 머리글 클릭 시 WPF List View/Grid View를 정렬하는 가장 좋은 방법? (0) | 2023.04.23 |
---|---|
@try - 목표 C의 캐치 블록 (0) | 2023.04.23 |
ASP.Net 웹 응용 프로그램 추가 구성 변환이 회색으로 표시됨 (0) | 2023.04.23 |
메서드 이름과 행 번호를 출력하여 NSLog를 조건부로 비활성화하려면 어떻게 해야 합니까? (0) | 2023.04.18 |
엔티티 프레임워크테이블의 모든 행 삭제 (0) | 2023.04.18 |