2009-09-23 2 views
7

미리 정의 된 값 목록의 값을 테스트 용 테이블에 무작위로 삽입하려고합니다. 삽입되는 내 "임의"값을 모두 정확하게 모든 3000 개 기록에 대해 동일합니다, 나는 내가 이것을 시도했을 때SQL Server 테이블에 임의의 값을 삽입하려면 어떻게해야합니까?

stackoverflow.com/.../update-sql-table-with-random-value-from-other-table

:이 StackOverflow의 질문에있는 솔루션을 사용했습니다.

실제로 임의의 행을 선택하는 쿼리 부분을 실행할 때마다 수동으로 실행할 때마다 임의의 레코드를 선택하므로 쿼리가 작동하는 것입니다. 무슨 일이 일어나고 있는지에 관해서는 내 최고의 추측은 다음과 같습니다

  • SQL Server는 하위 쿼리가 임의의 값의 씨앗은 모든 기록에 동일 한 번
  • 이상을 평가하는 것을 허용하지, 어떻게 든 SELECT 최적화 된 쿼리 업데이트

내 옵션이 무엇인지 파악하고 있습니다. 나는 잘못된 것을하고 있습니까, 아니면 제가해야 할 다른 방법이 있습니까?

내가 사용하고 코드입니다 : 지금이 권리를 확인하는 시간이 없어

DECLARE @randomStuff TABLE ([id] INT, [val] VARCHAR(100)) 

INSERT INTO @randomStuff ([id], [val]) 
VALUES (1, 'Test Value 1') 
INSERT INTO @randomStuff ([id], [val]) 
VALUES (2, 'Test Value 2') 
INSERT INTO @randomStuff ([id], [val]) 
VALUES (3, 'Test Value 3') 
INSERT INTO @randomStuff ([id], [val]) 
VALUES (4, 'Test Value 4') 
INSERT INTO @randomStuff ([id], [val]) 
VALUES (5, 'Test Value 5') 
INSERT INTO @randomStuff ([id], [val]) 
VALUES (6, null) 
INSERT INTO @randomStuff ([id], [val]) 
VALUES (7, null) 
INSERT INTO @randomStuff ([id], [val]) 
VALUES (8, null) 
INSERT INTO @randomStuff ([id], [val]) 
VALUES (9, null) 
INSERT INTO @randomStuff ([id], [val]) 
VALUES (10, null) 

UPDATE MyTable 
SET MyColumn = (SELECT TOP 1 [val] FROM @randomStuff ORDER BY NEWID()) 
+0

이 질문/답변 유용 할 수 있습니다 : http://stackoverflow.com/a/9039661/47226 –

답변

14

...

(SELECT TOP 1 [val] FROM @randomStuff ORDER BY NEWID()) 

를했다 ... 그것은 모두 "처럼, 우하는 캐시 할 스칼라 하위 쿼리, I 그걸 캐치 겠어! "

쿼리 엔진을 캐치 할 수 없다고 생각하도록 트릭해야합니다. jfar의 answer은 가깝지만 쿼리 엔진은 tautalogy가 MyTable.MyColumn = MyTable.MyColumn 인 것을 볼 수있을만큼 똑똑했지만이 사실을 충분히 볼 수는 없습니다. 서브 쿼리에 외부 테이블 (MT)에 가져 와서

UPDATE MyTable 
    SET MyColumn = (SELECT TOP 1 val 
        FROM @randomStuff r 
          INNER JOIN MyTable _MT 
            ON M.Id = _MT.Id 
        ORDER BY NEWID()) 
FROM MyTable M 

는 쿼리 엔진은 하위 쿼리를 다시 평가해야합니다 가정합니다. 아무 것도 실제로 작동하지만 MyTable.Id의 기본 키 (가정)는 인덱싱되므로 오버 헤드가 거의 발생하지 않습니다.

커서는 아마도 빠를 것이지만 가장 재미있을 것 같지 않습니다.

+0

OK, SQL Server 2000에서 INNER JOIN을 할 수 있는지 기억이 나지 않습니다.하지만 2005 년 전에 항상 사용했던 방법이 있습니다. 너무 오래 전에 저를 기억하고있었습니다. 그래도. 그러나 이것은 2005 년에 작동 할 것이고 나중에 괜찮아 질 것입니다. –

+1

잘 작동했습니다. 고맙습니다! –

+2

+1 이것은 환상적입니다. 작은 오타가 있습니다. 'ON MT.Id = _MT.Id'는'켜짐 M.Id = _MT.Id'이어야합니다. – Rippo

0

하지만 내 직감은 저에게 말한다 당신이 얻을 수있는 서버에 함수를 작성한다면 그것을 최적화하지 않을 임의의 값.

당신은 여기에 무슨 더 최적화가 없습니다

UPDATE MyTable 
Set MyColumn = dbo.RANDOM_VALUE() 
0

것이다.

단일 값을 선택하는 하위 쿼리를 사용하면 최적화 할 항목이 없습니다.

테이블의 항목을 선택하여 업데이트하고 변경 사항이 있는지 확인할 수도 있습니다. 즉 십자가에 가입

UPDATE MyTable 
SET MyColumn = (SELECT TOP 1 [val] FROM @randomStuff ORDER BY NEWID() 
    WHERE MyTable.MyColumn = MyTable.MyColumn) 
+1

방금 ​​시도. 결과가 바뀌지 않았다. –

2

사용이 임의의 데이터

+0

사용할 수있는 예가 있습니까? 나는 십자가 조인이라는 개념에 익숙하지 않습니다. –

0

내가 해킹의 비트와 매우 비효율적 (10 ~ 초는 해결책을 내놓았다을 생성하는 MyTable에있는 모든 행에 대해 평가를 트리거 할 수 3000 레코드 갱신). 이것은 테스트 데이터를 생성하는 데 사용되기 때문에 속도에 신경 쓰지 않아도됩니다.

이 솔루션에서는 테이블의 모든 행을 반복하고 값을 한 번에 한 행씩 업데이트합니다. 그것은 작동하는 것 같다 :

DECLARE @rows INT 
DECLARE @currentRow INT 

SELECT @rows = COUNT(*) FROM dbo.MyTable 
SET @currentRow = 1 

WHILE @currentRow < @rows 
BEGIN 

UPDATE MyTable 
SET MyColumn = (SELECT TOP 1 [val] FROM @randomStuff ORDER BY NEWID()) 
WHERE MyPrimaryKey = (SELECT b.MyPrimaryKey 
FROM(SELECT a.MyPrimaryKey, ROW_NUMBER() OVER (ORDER BY MyPrimaryKey) AS rownumber 
     FROM MyTable a) AS b 
WHERE @currentRow = b.rownumber 
) 

SET @currentRow = @currentRow + 1 
END 
1

나는 이것과 놀아 보았고, 중간 테이블 변수를 사용하여 그것을 해치는 방법을 발견했다. @randomStuff가 설정되면

, 우리는이 이렇게 (내 경우에는 메모를, @MyTable은 일반 테이블 따라 조정 테이블 변수) :이 시점에서 너무

DECLARE @randomMappings TABLE (id INT, val VARCHAR(100), sorter UNIQUEIDENTIFIER) 

INSERT INTO @randomMappings 
SELECT M.id, val, NEWID() AS sort 
FROM @MyTable AS M 
CROSS JOIN @randomstuff 

, 우리는이 (mytable id, 임의의 값) 및 해당 조합에 특정한 각 행에 대한 임의의 정렬 값의 모든 조합이있는 중간 테이블.그런 다음

DELETE others FROM @randomMappings AS others 
INNER JOIN @randomMappings AS lower 
ON (lower.id = others.id) AND (lower.sorter < others.sorter) 

이 낮은 정렬 값으로 하나를 제외하고 주어진 MyTable.id에 대한 모든 행을 삭제 오래된 트릭입니다 - 값이 작은 자체에 테이블을 조인과 장소 등 모든 삭제 조인이 성공했습니다. 이것은 단지 가장 낮은 가치를 남깁니다.

UPDATE @MyTable 
SET MyColumn = random.val 
FROM @MyTable m, @randomMappings AS random 
WHERE (random.id = m.id) 

를 그리고이 완료 : 그래서 각 MyTable.id, 우리는 하나 (임의) 값이 그 다음 우리는 그냥 테이블에 연결 .. 남아있다!

나는 은 해키했다 ... 쿼리 엔진이를보고

관련 문제