如何根据一个字段的计数更新四个字段

时间:2017-12-01 16:52:07

标签: sql sql-server

我有一张表有ID的表;每个SourceID可以有1到4个唯一ID。我创建了一个CTE来计算所有唯一ID,从1到4,如下所示。

enter image description here

基于CNT,并加入sourceid_revised加上asofdate,我想更新另一个带有ID的表,如下图所示。

enter image description here

伪代码看起来像这样:

UPDATE  RAW_DATA 
SET 
    RAW_DATA.ID1 = case when Count_Of_IDs.cnt=1 then FIRST(PID) end,
    RAW_DATA.ID2 = case when Count_Of_IDs.cnt=2 then SECOND(PID) end,
    RAW_DATA.ID3 = case when Count_Of_IDs.cnt=3 then THIRD(PID) end,
    RAW_DATA.ID4 = case when Count_Of_IDs.cnt=4 then Forth(PID) end
FROM   RAW_DATA INNER JOIN
       Count_Of_IDs ON RAW_DATA.SourceID_Revised = Count_Of_IDs.Sourceid_Revised AND 
       RAW_DATA.AsofDate = Count_Of_IDs.asofdate

我正在使用SQL Server 2008。

更新!

我认为编辑原始帖子最简单,而不是发表评论。这部分似乎有效。

select *, count(PID) over (partition by SourceID_Revised) RN
FROM [dbo].[RAW_DATA]

所以,RN永远不应该大于4.这似乎工作得很好,但我不能让其余的工作。我正在测试dense_rank版本,并且我在这一行上一直收到错误:

cte2 as (

错误= Incorrect syntax near 'cte2'

这几乎看起来应该有用......

Select SourceID_Revised, ID, ID1, ID2, ID3, ID4, RN
    Set ID1 = max(case when RN = 1 then ID end),
    Set ID2 = max(case when RN = 2 then ID end),
    Set ID3 = max(case when RN = 3 then ID end),
    Set ID4 = max(case when RN = 4 then ID end)
FROM
(
select SourceID_Revised, ID, ID1, ID2, ID3, ID4, count(ID) over (partition by SourceID_Revised) RN
FROM [dbo].[RAW_DATA]
) AS Summary

......但当然没有。

1 个答案:

答案 0 :(得分:1)

我认为这就是你要找的东西。但是,我不太确定你真的想要更新源表而不是仅仅提供这个(下面的最终选择)。更新bean将需要删除重复的行(忽略ID列)。如果这真的是欲望,我会让你处理。如果是我的话,我会离开它并简单地呈现它。

with cte as(
select *, row_number() over (partition by SourceID_Revised order by ID, AsOfDate) RN
FROM yourTable
),

cte2 as (
select 
    SourceID_Revised
    ,AsOfDate
    ,ID = NULL
    ,ID1 = max(case when RN = 1 then ID end)
    ,ID2 = max(case when RN = 2 then ID end)
    ,ID3 = max(case when RN = 3 then ID end)
    ,ID4 = max(case when RN = 4 then ID end)
group by
    SourceID_Rebised
    ,AsOfDate
from cte)


select * from cte2

--UPDATE  R
--set
--  R.PID1 = ID1
--  ...
--from RAW_DATA R
--inner join cte2 on 
--cte2.SourceID_Revised = r.SourceID_Revised

另外,您可以使用count(ID) over (partition by SourceID_Revised) RN,但如果两个ID具有相同的计数,那么您将如何处理?因此,我可能会在第二次CTE中使用DENSE_RANK()。像......那样......

with cte as(
select *, count(ID) over (partition by SourceID_Revised) RN
FROM YourTable
),

ctex as(
select *, dense_rank() over (partition by  SourceID_Revised order by RN, ID) RN2
from cte)

cte2 as (
select 
    SourceID_Revised
    ,AsOfDate
    ,ID = NULL
    ,ID1 = max(case when RN2 = 1 then ID end)
    ,ID2 = max(case when RN2 = 2 then ID end)
    ,ID3 = max(case when RN2 = 3 then ID end)
    ,ID4 = max(case when RN2 = 4 then ID end)
group by
    SourceID_Rebised
    ,AsOfDate
from ctex)


select * from cte2