2015-05-29 14 views
6

Rozważmy te dane:Aktualizacja tabeli przy użyciu losowo wielu wartości w innej tabeli

CREATE TABLE #Data (DataID INT, Code VARCHAR(2), Prefix VARCHAR(3)) 

INSERT INTO #Data (DataID, Code) 
VALUES (1, 'AA') 
, (2, 'AA') 
, (3, 'AA') 
, (4, 'AA') 
, (5, 'AA') 
, (6, 'AA') 

CREATE TABLE #Prefix (Code VARCHAR(2), Prefix VARCHAR(3)) 

INSERT INTO #Prefix (Code, Prefix) 
VALUES ('AA', 'ABC') 
, ('AA', 'DEF') 
, ('AA', 'GHI') 
, ('AA', 'JKL') 

Chcę ustawić wartość Prefix w #Data być losowy Prefix z #Prefix z dopasowania Code.

Stosując prostą inner join tylko skutkuje jedna wartość jest używana:

UPDATE D 
SET Prefix = P.Prefix 
FROM #Data AS D 
INNER JOIN #Prefix AS P ON D.Code = P.Code 

Od przeczytaniu innych pytań dotyczących tu NEWID() jest zalecane jako sposób losowy zamawiania czegoś. Zmiana join do:

SELECT TOP 1 subquery ordering by NEWID() 

nadal wybiera tylko jedną wartość (choć za każdym razem losowo) dla każdego wiersza:

UPDATE D 
SET Prefix = (SELECT TOP 1 P.Prefix FROM #Prefix AS P WHERE P.Code = D.Code ORDER BY NEWID()) 
FROM #Data AS D 

więc nie jestem pewien, jak się losowo dla każdego prefiksu wprowadzanie danych z pojedynczej instrukcji aktualizacji. Prawdopodobnie mogłabym wykonać jakąś pętlę przez stół #Data, ale unikam dotykania pętli w SQL i jestem pewien, że będzie wolno. Faktyczne zastosowanie tego będzie dotyczyć dziesiątków tysięcy rekordów, z setkami prefiksów dla dziesiątek kodów.

Odpowiedz

8

To jak to zrobić:

UPDATE d SET Prefix = ca.Prefix 
FROM #Data d 
CROSS APPLY(SELECT TOP 1 Prefix 
      FROM #Prefix p 
      WHERE d.DataID = d.DataID AND p.Code = d.Code ORDER BY NEWID()) ca 

Wskazówka d.DataID = d.DataID. To jest tutaj, aby zmusić silnik Sql Server do ponownej oceny podzapytania dla każdego wiersza tabeli #Data.

Powiązane problemy