使用SQL GROUP BY CASE语句更新表

时间:2014-03-26 21:36:05

标签: sql-server sql-server-2008 tsql

DimAward
--------  
AwardKey (PK)  
TypeCode  
SourceCode  
SourceKey  

CREATE TABLE [Final].[DimAward](
    [AwardKey] [int] IDENTITY(1,1) NOT NULL,
    [SourceKey] [varchar](10) NOT NULL,
    [SourceCode] [varchar](10) NOT NULL,
    [TypeCode] [varchar](10) NOT NULL,
 CONSTRAINT [pk_DimAward] PRIMARY KEY NONCLUSTERED 
(
    [AwardKey] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY],
 CONSTRAINT [uq_DimAward_SourceKey] UNIQUE CLUSTERED 
(
    [SourceKey] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) 
ON [PRIMARY]
) ON [PRIMARY]

GO

FactAwardDetail
----------------
AwardKey (FK to DimAward.AwardKey)  
AidYearkey  
StudentKey  
TermKey  
AwardLevelKey  

CREATE TABLE [Final].[FactAwardDetail](
    [AwardDetailKey] [int] IDENTITY(1,1) NOT NULL,
    [AwardKey] [int] NOT NULL,
    [AidYearKey] [int] NOT NULL,
    [StudentKey] [int] NOT NULL,
    [TermKey] [int] NOT NULL,
    [AwardLevelKey] [int] NOT NULL,
 CONSTRAINT [pk_FactAwardDetail] PRIMARY KEY NONCLUSTERED 
(
    [AwardDetailKey] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY],
 CONSTRAINT [uq_FactAwardDetail_CompoundID] UNIQUE NONCLUSTERED 
(
    [StudentKey] ASC,
    [AidYearKey] ASC,
    [TermKey] ASC,
    [AwardKey] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

FactAwardDetail有给定StudentKey / AidYearkey / Termkey的多个记录(学生在给定的援助年限/学期内可以有多个奖励) - 可能需要按StudentKey,AidYearkey,TermKey进行分组。

FactAward Sample data DimAward Sample data

我需要根据以下逻辑使用FactAwardDetail.AwardKey更新FactAwardDetail.AwardLevelKey。

如果给定StudentKey / AidYearKey / TermKey组合的任何记录满足以下条件:

SELECT 1  
From DimAward a INNER JOIN  
FactAwardDetail ad on a.AwardKey = ad.AwardKey  
Where a.SourceKey = 'powell'  
group by ad.StudentKey, ad.AidYearKey, ad.TermKey  

然后

set ad.AwardLevelkey = ad.awardkey  
set ad.AwardLevelKey for remaining records for the same StudentKey/AidYearkey/Termkey combination to -1

如果没有记录满足上述条件,则查找新条件如下: 如果给定StudentKey / AidYearkey / Termkey组合的任何记录满足以下条件:

SELECT 1
From DimAward a INNER JOIN
FactAwardDetail ad on a.AwardKey = ad.AwardKey
Where a.SourceKey = 'regt'
group by ad.StudentKey, ad.AidYearKey, ad.TermKey

然后

set ad.AwardLevelkey = ad.awardkey
set rest of ad.AwardLevelKey for remaining records for the same StudentKey/AidYearkey/Termkey combination to -1

如果没有记录满足上述两个条件,则按如下方式寻找新条件:

如果给定StudentKey / AidYearkey / Termkey组合的任何记录满足以下条件:

SELECT 1
From DimAward a INNER JOIN
FactAwardDetail ad on a.AwardKey = ad.AwardKey
Where a.SourceKey = 'presm'
group by ad.StudentKey, ad.AidYearKey, ad.TermKey

然后     设置ad.AwardLevelkey = ad.awardkey     将其余的ad.AwardLevelKey设置为同一StudentKey / AidYearkey / Termkey组合的剩余记录为-1

如果没有记录满足上述3个条件,我将需要多次重复此模式。

感谢您撰写t-sql语句的任何帮助。

1 个答案:

答案 0 :(得分:1)

你不能像if-then-else这样的结构。 SQL是为集合操作而设计的,所以请以这种方式使用它。首先,您需要有一个SourceKeys的有序列表:

declare @SourceKeyPriority table
(
  Priority int, SourceKey varchar(10)
)
insert into @SourceKeyPriority values (1,'powell')
insert into @SourceKeyPriority values (2,'regt')
insert into @SourceKeyPriority values (3,'presm')

它不需要是表变量,只是适合你的任何东西。然后将所有记录更新为-1我们将随后更新那些具有匹配奖励的行。然后,您需要找到适合给定ad.StudentKey,ad.AidYearKey,ad.TermKey组合的最佳(最高优先级)。将其包裹在CTE中并使用它来更新您的表:

with cte as
(
  select 
    ad.StudentKey, 
    ad.AidYearKey, 
    ad.TermKey, 
    min(x.Priority) as Priority
  from 
    @SourceKeyPriority x
    inner join DimAward a
      on a.SourceKey = x.SourceKey
    inner join FactAwardDetail ad 
      on a.AwardKey = ad.AwardKey
  group by 
    ad.StudentKey, ad.AidYearKey, ad.TermKey
)
update ad
set AwardLevelKey = ad.AwardKey
from FactAwardDetail ad
inner join cte 
  on cte.StudentKey = ad.StudentKey
  and cte.AidYearKey = ad.AidYearKey
  and cte.TermKey = ad.TermKey
inner join @SourceKeyPriority x
  on x.Priority = cte.priority
inner join DimAward a
  on a.SourceKey = x.SourceKey
  and a.AwardKey = ad.AwardKey