我需要一种方法来获取KeyID的结果集并将其尽可能平均分配,并根据KeyID为每个部门更新记录。换句话说,有
SELECT KeyID
FROM TableA
WHERE (some criteria exists)
我想通过3个相等的KeyID更新TableA 3的不同方式。
UPDATE TableA
SET FieldA = Value1
WHERE KeyID IN (the first 1/3 of the SELECT resultset above)
UPDATE TableA
SET FieldA = Value2
WHERE KeyID IN (the second 1/3 of the SELECT resultset above)
UPDATE TableA
SET FieldA = Value3
WHERE KeyID IN (the third 1/3 of the SELECT resultset above)
或其他相似之处。感谢您的任何和所有回复。
答案 0 :(得分:4)
With TiledItems As
(
Select KeyId
, NTILE(3) OVER( ORDER BY ... ) As NTileNum
From TableA
Where ...
)
Update TableA
Set FieldA = Case TI.NTileNum
When 1 Then Value1
When 2 Then Value2
When 3 Then Value3
End
From TableA As A
Join TiledItems As TI
On TI.KeyId = A.KeyId
答案 1 :(得分:2)
不幸的是,我没有时间敲定一个完整的解决方案,但其中一个要点是使用带有NTILE函数http://msdn.microsoft.com/en-us/library/ms175126.aspx的CTE分成3组,然后在UPDATE语句中加入到CTE中并针对NTILE组执行CASE语句,以确定是使用Value1,Value2还是Value3。
修改强> 请参阅Thomas's回答代码,看起来他有同样的想法!
答案 2 :(得分:1)
对于简单分发,创建随机排名并以3 ...
为模UPDATE
A
SET
FieldA =
CASE Ranking % 3
WHEN 1 THEN B.Value1
WHEN 2 THEN B.Value2
WHEN 0 THEN B.Value3
END
FROM
TableA A
inner join
(SELECT
ID,
ROW_NUMBER() OVER (ORDER BY ID /*or something*/) AS Ranking,
Value1, Value2, Value3
FROM
TableA
) B on A.ID = B.ID
where (some criteria exists)
您可以更改ROW_NUMBER()的ORDER BY,或使用NTILE并删除模数
答案 3 :(得分:1)
如果密钥均匀分布,则可以使用模数(%
)运算符选择结果集的唯一三分之一。
update TableA set FieldA = Value1 where KeyID % 3 = 0;
update TableA set FieldA = Value2 where KeyID % 3 = 1;
update TableA set FieldA = Value3 where KeyID % 3 = 2;
答案 4 :(得分:0)
按字面解释你所说的内容,你可以对返回的行集中的行进行编号,然后根据行号选择不同的部分。
E.g。
UPDATE TableA
SET FieldA = Value1
WHERE KeyID IN (SELECT * FROM (SELECT <your rows>, ROW_NUMBER() (ORDER BY <anyRow>) AS RowNumber FROM <yourTable> ) base
WHERE RowNumber<Count(RowNumber)/3)
UPDATE TableA
SET FieldA = Value1
WHERE KeyID IN (SELECT * FROM (SELECT <your rows>, ROW_NUMBER() (ORDER BY <anyRow>) AS RowNumber FROM <yourTable> ) base
WHERE RowNumber<Count(RowNumber)*2/3 && RowNumber>=Count(RowNumber)/3)
UPDATE TableA
SET FieldA = Value1
WHERE KeyID IN (SELECT * FROM (SELECT <your rows>, ROW_NUMBER() (ORDER BY <anyRow>) AS RowNumber FROM <yourTable> ) base
WHERE owNumber>=Count(RowNumber)*2/3)
答案 5 :(得分:0)
WITH Query (OtherKeyID, PCT)
AS
(
SELECT KeyID, (ROW_NUMBER() OVER (ORDER BY KeyID)) / foo.CNT AS PCT
FROM TableA
JOIN (SELECT CONVERT(float, COUNT(1)) AS CNT FROM TableA) foo ON 1 = 1
WHERE (criteria)
)
UPDATE TableA
SET FieldA = (CASE
WHEN PCT < .3333 THEN Value1
WHEN PCT BETWEEN .3333 and .6666 THEN Value2
WHEN PCT > .6666 THEN Value3 ELSE NULL END)
FROM Query
WHERE KeyID = OtherKeyID AND PCT < .3333
请注意,您可以将查询中的ORDER BY
子句更改为任何有效的表达式,这样您就可以按任何条件定义“前三分之一”。