Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server/T-SQL:如何更新结果集的相等百分比?_Sql_Sql Server_Tsql - Fatal编程技术网

SQL Server/T-SQL:如何更新结果集的相等百分比?

SQL Server/T-SQL:如何更新结果集的相等百分比?,sql,sql-server,tsql,Sql,Sql Server,Tsql,我需要一种方法来获取keyid的结果集,并将其尽可能平均地划分,并根据keyid为每个划分更新不同的记录。换句话说,有 SELECT KeyID FROM TableA WHERE (some criteria exists) 我想用3个相等的keyid部分以3种不同的方式更新TableA UPDATE TableA SET FieldA = Value1 WHERE KeyID IN (the first 1/3 of the SELECT resultset above) U

我需要一种方法来获取keyid的结果集,并将其尽可能平均地划分,并根据keyid为每个划分更新不同的记录。换句话说,有

SELECT KeyID
FROM   TableA
WHERE (some criteria exists)
我想用3个相等的keyid部分以3种不同的方式更新TableA

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)

或者类似的东西。感谢您的所有回复。

从字面上理解您所说的,您可以对返回行集中的行进行编号,然后根据行编号选择不同的分段

例如


对于一个简单的分布,创建一个随机排名和模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)

您可以通过更改行号的顺序,或者使用NTILE并删除模

不幸的是,我没有时间想出一个完整的解决方案,但其中的要点是使用带有NTILE函数的CTE将其分成3组,然后在UPDATE语句中加入该CTE,并对NTILE组执行CASE语句,以确定是否使用值1、值2,或价值3

编辑 请参阅此代码的答案,因为看起来他有相同的想法

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子句更改为任何有效表达式,这将允许您根据任何条件定义前三分之一。

如果键均匀分布,则可以使用模数%运算符选择结果集的唯一三分之一

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;

完美的布里里安!!正是我需要的!感谢所有回答的人,尤其是马丁和托马斯。
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;
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