第一次询问-我在SqlServer 2012中将大小写逻辑和窗口组合在一起时遇到一些问题。我需要展平以下所示的数据结构,因此以后将针对这些结果运行MAX语句。我正在使用case / when逻辑为每个xID指定一个“所有者”。我面临的挑战是,我一直在得到错误的结果,而我无法确定自己在做错什么。
这是大小写/逻辑和表结构。对于“所有者”列,我需要评估三个条件,并试图使用FIRST_VALUE()选择case语句的输出。 case语句中的逻辑正常工作,但是当我尝试使用窗口函数将值应用于每个xID时,它将返回错误的值。
FIRST_VALUE(case
when [partnerType] = 'Giver' and [partnerAgree] = 'True' then [partnerGroup]
when [partnerType] = 'Impacted' and [partnerAgree] = 'True' then [partnerGroup]
when [Stakeholder No#] = 1 and [partnerAgree] <> 'True' then [partnerGroup]
else Null end) over (partition by [xID] order by [yID])
as 'Owner'
Desired Results --------------------------
|xID|yID| Owner |partnerType| partnergrp|partnerAgree
|100| 1| grp_Banana|Taker |grp_Apple |TRUE
|100| 2| grp_Banana|Giver |grp_Banana |TRUE
|100| 3| grp_Banana|Taker |grp_Banana |FALSE
|101| 1| grp_Carrot|Taker |grp_Carrot |TRUE
|101| 2| grp_Carrot|Giver |grp_Danish |FALSE
|101| 3| grp_Carrot|Taker |grp_Banana |TRUE
|101| 4| grp_Carrot|Taker |grp_Danish |FALSE
Results I'm getting --------------------------
|xID|yID| Owner |partnerType| partnergrp|partnerAgree
|100| 1| grp_Apple |Taker |grp_Apple |TRUE
|100| 2| grp_Apple |Giver |grp_Banana |TRUE
|100| 3| grp_Apple |Taker |grp_Banana |FALSE
|101| 1| grp_Carrot|Taker |grp_Carrot |TRUE
|101| 2| grp_Carrot|Giver |grp_Danish |FALSE
|101| 3| grp_Carrot|Taker |grp_Banana |TRUE
|101| 4| grp_Carrot|Taker |grp_Danish |FALSE
第一个表显示了我期望的结果,但是代码在第二个表中产生了值。示例:对于xID = 100,我希望所有者为grp_Banana,但是我的代码返回grp_Apple。对于xID = 101,我得到了正确的答案,但是原因有误。窗口函数似乎对任何结果集都采用第一个yID。
感谢您的帮助。另外,我愿意不使用开窗功能,这似乎是正确的方向。
答案 0 :(得分:2)
除非您的数据库支持ignore null
s参数,否则这很棘手。您可以使用两个窗口功能来做到这一点:
max(case when yid = yid_special then partnerGroup end) over (partition by xid) as Owner
from (select . . . ,
min(case when partnerType = 'Giver' and [partnerAgree] = 'True' then yid
when partnerType = 'Impacted' and [partnerAgree] = 'True' then yid
when [Stakeholder No#] = 1 and [partnerAgree] <> 'True' then yid
end) over (partition by xid) as yid_special
您也许还可以使用first_value()
来编写此代码:
first_value(partnerGroup) over
(partition by xid
order by (case when partnerType = 'Giver' and [partnerAgree] = 'True' then yid
when partnerType = 'Impacted' and [partnerAgree] = 'True' then yid
when [Stakeholder No#] = 1 and [partnerAgree] <> 'True' then yid
else 999999
end)
) as owner
答案 1 :(得分:0)
使用@ Gordon-Linoff的建议,我能够解决我的问题。这是修改后的代码。在Order By中看到Gordon对case语句的使用使我意识到为什么我的代码有时选择错误的值。因为我只是基于他的方法,所以我相信他的答案。非常感谢。
, FIRST_VALUE(
case
when [partnerType] = 'Remediator' and [partnerAgree] = 'True' then [partnerGroup]
when [partnerType] = 'Impacted' and [partnerAgree] = 'True' then [partnerGroup]
when [yID] = 1 and [partnerAgree] <> 'True' then [partnerGroup]
else [partnerGroup] end)
over
(partition by [Incident ID] order by
case
when [partnerType] = 'Remediator' and [partnerAgree] = 'True' then 1
when [partnerType] = 'Impacted' and [partnerAgree] = 'True' then 2
when [yID] = 1 and [partnerAgree] <> 'True' then 3
else 100
end
)
as 'Owner'