2016-09-27 46 views
1

我有一些记录,我正在从一个表格移动到另一个表格,并进行一些操作。SQL更新每个不同的一半

我已经把它们放在临时表中,这样我就可以进行操作了。具体而言,我需要换一个不同的值的一半到的东西列,那么另一半变成别的东西:

在我的临时表,我有

Animals | SeveralOtherColumns 
dog 
cat 
fish 
dog 
dog 
dog 
fish 
cat 
cat 
cat 

,我需要有

Animals | SeveralOtherColumns 
dog_A 
cat_A 
fish_A 
dog_A 
dog_B 
dog_B 
fish_B 
cat_A 
cat_B 
cat_B 

我不知道Animals中有什么不同的值,或者每个不同的值会有多少。

所以我最初的想法是:

SET @count = (SELECT COUNT(DISTINCT(Animals)) FROM #temptable) 

--this throws an error, doesn't like the assignment 
SET @animals = (SELECT DISTINCT(Animals) FROM #temptable) 

WHILE (@count > 0) 
BEGIN 
    -- about here is where I'm lost 
    -- update the first half of the distinct value 
    UPDATE #temptable SET #temptable.Animals = #temptable.Animals + '_A' 
    WHERE Animals = @animals[@count] --Pretty sure this won't work but gets the point across 
    FROM (SELECT TOP 50 PERCENT FROM #temptable) 

    -- update the remaining set of that distinct value 
    UPDATE #temptable SET #temptable.Animals = #temptable.Animals + '_B' 
    WHERE Animals = @animals[@count] 
    FROM #temptable 


    SET @count = @count - 1 
END 
+1

后缀的逻辑是什么?不明白 – Lamak

+0

你需要任何sql server的兼容性,还是最新版本是你的目标? – infiniteRefactor

+0

@Lamak每个不同值的前半部分都被附加了_A,其余部分被附加了_B。用人类语言来解释这种奇怪的... –

回答

5

您可以使用NTILE()

WITH CTE AS 
(
    SELECT *, 
      N = NTILE(2) OVER(PARTITION BY Animals ORDER BY Animals) 
    FROM dbo.Animals 
) 
UPDATE CTE 
SET Animals = Animals + CASE WHEN N = 1 THEN '_A' ELSE '_B' END 
; 
+0

我忘了'NTILE()' - 我喜欢这种方法好多了! – Siyual

3

可以使用ROW_NUMBER()和检查mod (%2)把它们分为相等的组为此在单CTE

;With Cte As 
(
    Select *, 
      Row_Number() Over (Partition By Animals Order By Animals) As RN 
    From #TempTable 
) 
Update Cte 
Set  Animals = Animals + Case When RN % 2 = 0 
           Then '_A' 
           Else '_B' 
          End