繁体   English   中英

SQL - 使用窗口和case语句展平表

[英]SQL - Flattening a table using windowing and case statements

第一次提问者 - 我在SqlServer 2012中将案例逻辑和窗口结合起来时遇到了一些问题。我需要展平下面显示的数据结构,因此我将针对这些结果运行MAX语句。 我正在使用case / when逻辑来为每个xID指定一个“Owner”。 我的挑战是我一直得到错误的结果,我无法确定我做错了什么。

这是/逻辑和表结构的情况。 对于'Owner'列,我需要评估三个条件,并尝试使用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。

谢谢,任何帮助表示赞赏。 此外,我愿意不使用窗口功能,它似乎是正确的方向。

除非您的数据库支持ignore null的参数,否则这很棘手。 您可以使用两个窗口函数执行此操作:

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

使用@ Gordon-Linoff的建议,我能够解决我的问题。 这是修改后的代码。 看到Gordon在Order By中使用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'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM