使用 Group By 时,完全外部联接显示 NULL

gue*_*est 3 null join sql-server group-by

我有 4 个子查询,每个子查询都按“组名”分组。尝试将每个子查询作为一个列,全部按“组名”分组。这是查询:

select  
    coalesce(co.group_name, requests.group_Name, incidents.group_Name, problems.group_Name) as 'SD Groups'
    , isnull(co.co, '') as 'CO'
    , isnull(incidents.incidents, '' ) as 'Inc'
    , isnull(problems.problems, '') as 'Prob'
    , isnull(requests.requests, '') as 'Rqst'
from
    (
    select 
        groups.last_name AS Group_Name   
        ,count(chg_ref_num)  AS 'CO'
    from chg
    left join   ca_contact groups 
        on chg.group_id = groups.contact_uuid 
    left join   ca_contact assignee 
        on chg.assignee = assignee.contact_uuid 
    left join   ca_company cc 
        on  assignee.company_uuid = cc.company_uuid                       
    where   
        groups.last_name in ('8197 Qlikview Support', '8202 OBIEE-BIP'
                        , '8205 BI SAS', '8206 BI CCBI', '8208 BI ePlan Reporting and Support'
                        , '8211 BI Data Quality', '8212 BI EPM Report Architect/Developer'
                        , '8213 BI EPM Framework Architect/Developer', '8214 BI EPM User Experience'
                        , '8215 BI EPM OLAP Architect/Developer', '8219 BI Data Warehouse') 
        and status = 'CL'
        and     convert(varchar, dateadd(hh,-8,dateadd(ss,chg.close_date, '1970')), 101)  >= DATEADD(month, datediff(month, 0, getdate()), 0)
        and     parent is NULL  
        and     cc.company_name = 'XYZ' 
    group by    groups.last_name
        ) as CO
full outer join 
    (
    select                         
        groups.last_name AS Group_Name   
        ,count(ref_num) AS Requests
    from call_req cr                                
    left join   ca_contact groups 
        on cr.group_id = groups.contact_uuid  
    left join   ca_contact assignee 
        on cr.assignee = assignee.contact_uuid  
    left join   ca_company cc 
        on  assignee.company_uuid = cc.company_uuid                       
    where   
        groups.last_name in ('8197 Qlikview Support', '8202 OBIEE-BIP'
                        , '8205 BI SAS', '8206 BI CCBI', '8208 BI ePlan Reporting and Support'
                        , '8211 BI Data Quality', '8212 BI EPM Report Architect/Developer'
                        , '8213 BI EPM Framework Architect/Developer', '8214 BI EPM User Experience'
                        , '8215 BI EPM OLAP Architect/Developer', '8219 BI Data Warehouse')                         
        and     cr.status in ('CL')     
        and     convert(varchar, dateadd(hh,-8,dateadd(ss,cr.close_date, '1970')), 101)  >= DATEADD(month, datediff(month, 0, getdate()), 0)                    
        and     cr.parent is NULL   
        and     cr.type = 'R'   
        and     cc.company_name = 'XYZ'                 
    group by    groups.last_name, cr.type
        ) as Requests
    on co.group_name = requests.group_name
full outer join
    (
    select                                 
        groups.last_name AS Group_Name   
        ,count(ref_num) AS Problems
    from call_req cr                                
    left join   ca_contact groups 
        on cr.group_id = groups.contact_uuid
    left join   ca_contact assignee 
        on cr.assignee = assignee.contact_uuid  
    left join   ca_company cc 
        on  assignee.company_uuid = cc.company_uuid                               
    where   
        groups.last_name in ('8197 Qlikview Support', '8202 OBIEE-BIP'
                        , '8205 BI SAS', '8206 BI CCBI', '8208 BI ePlan Reporting and Support'
                        , '8211 BI Data Quality', '8212 BI EPM Report Architect/Developer'
                        , '8213 BI EPM Framework Architect/Developer', '8214 BI EPM User Experience'
                        , '8215 BI EPM OLAP Architect/Developer', '8219 BI Data Warehouse')                         
        and     cr.status in ('CL')     
        and     convert(varchar, dateadd(hh,-8,dateadd(ss,cr.close_date, '1970')), 101)  >= DATEADD(month, datediff(month, 0, getdate()), 0)                    
        and     cr.parent is NULL   
        and     cr.type = 'P'   
        and     cc.company_name = 'XYZ'             
    group by    groups.last_name, cr.type
    ) as Problems
    on  requests.group_name = problems.group_name

full outer join 
    (
    select                                 
        groups.last_name AS Group_Name   
        ,count(ref_num) AS Incidents
    from call_req cr                                
    left join   ca_contact groups 
        on cr.group_id = groups.contact_uuid  
    left join   ca_contact assignee 
        on cr.assignee = assignee.contact_uuid  
    left join   ca_company cc 
        on  assignee.company_uuid = cc.company_uuid                           
    where   
        groups.last_name in ('8197 Qlikview Support', '8202 OBIEE-BIP'
                        , '8205 BI SAS', '8206 BI CCBI', '8208 BI ePlan Reporting and Support'
                        , '8211 BI Data Quality', '8212 BI EPM Report Architect/Developer'
                        , '8213 BI EPM Framework Architect/Developer', '8214 BI EPM User Experience'
                        , '8215 BI EPM OLAP Architect/Developer', '8219 BI Data Warehouse')                         
        and     cr.status in ('CL')     
        and     convert(varchar, dateadd(hh,-8,dateadd(ss,cr.close_date, '1970')), 101)  >= DATEADD(month, datediff(month, 0, getdate()), 0)                    
        and     cr.parent is NULL   
        and     cr.type = 'I'   
        and     cc.company_name = 'XYZ'                 
    group by    groups.last_name, cr.type
    ) as Incidents
    on requests.group_name = incidents.group_name
order by 
    'SD Groups' asc  
Run Code Online (Sandbox Code Playgroud)

结果如下:

Group_Name                                     CO  Inc Prob Rqst
8197 Qlikview Support                           0   1   0   7
8202 OBIEE-BIP                                  0   4   0   11
8205 BI SAS                                     0   11  1   11
8206 BI CCBI                                   10   17  0   43
8208 BI ePlan Reporting and Support             0   0   0   4
8211 BI Data Quality                            0   0   0   12
8212 BI EPM Report Architect/Developer          0   3   1   5
8214 BI EPM User Experience                     0   2   0   0
8214 BI EPM User Experience                     0   0   1   0
8215 BI EPM OLAP Architect/Developer            0   15  0   2
8219 BI Data Warehouse                         16   71  4   13
Run Code Online (Sandbox Code Playgroud)

请注意 Group 8214 的两行。每个组应表示一次,Group 8214 的所需结果应为:

Group_Name                                     CO  Inc Prob Rqst
8214 BI EPM User Experience                     0   2   1   0
Run Code Online (Sandbox Code Playgroud)

代码中是否存在明显缺陷?我最好的估计是查看 coalesce 函数 - 我尝试过但失败了。在我的尝试中,有一段不友好的文章:

isnull(isnull(isnull(co.group_name, requests.group_Name), incidents.group_Name), problems.group_Name) 
Run Code Online (Sandbox Code Playgroud)

但同样的结果。

ype*_*eᵀᴹ 6

代码中是否存在明显缺陷?我最好的估计是查看合并函数 - ...

是的。一个问题是第二个(和第三个)FULL JOIN使用(派生)表的group_name列。结果,第 2 次和第 3 次完全联接分别取消了第 1 次和第 2 次完全联接。您的查询只有基本结构,从细节中剥离:

select  
    coalesce(co.group_name, requests.group_Name, incidents.group_Name, 
             problems.group_Name) as 'SD Groups'
    ---
from
    ( --- ) as CO
full outer join 
    ( --- ) as Requests
    on co.group_name = requests.group_name
full outer join
    ( --- ) as Problems
    on  requests.group_name = problems.group_name
full outer join 
    ( --- ) as Incidents
    on requests.group_name = incidents.group_name
Run Code Online (Sandbox Code Playgroud)

第一次完全加入后:

ON co.group_name = requests.group_name
Run Code Online (Sandbox Code Playgroud)

表 (groupsrequests) 中的行可能与另一个不匹配,并且空列填充了NULL值。

然后第二次完全连接发生:

ON requests.group_name = problems.group_name
Run Code Online (Sandbox Code Playgroud)

ON只有具有非 null 的行才能满足此条件requests.group_name。这基本上将这 2 个FULL连接转换为一个复杂的混乱,这几乎(但不完全)是 3 个表的完整连接。某些行不会匹配,特别地从表中的行coproblems具有相同group_name(但没有这样的行中的表中存在requests)将不被匹配,但将在不同的行中结束。

第三次完全加入:

ON requests.group_name = incidents.group_name
Run Code Online (Sandbox Code Playgroud)

会让事情变得更加复杂。因此,您的查询相当于(requests左连接到其他 3 个表)和 3 个反连接(3 个表中的每一个都带有requests)的并集:

select  
    ---
from
    ( --- ) as Requests
left outer join
    ( --- ) as CO
    on co.group_name = requests.group_name
left outer join
    ( --- ) as Problems
    on  requests.group_name = problems.group_name
left outer join 
    ( --- ) as Incidents
    on requests.group_name = incidents.group_name

union all 

select  
    ---
from
    ( --- ) as CO
left outer join
    ( --- ) as Requests
    on co.group_name = requests.group_name
where 
    requests.group_name is null

union all 

select  
    ---
from
    ( --- ) as Problems
left outer join
    ( --- ) as Requests
    on problems.group_name = requests.group_name
where 
    requests.group_name is null

union all 

select  
    ---
from
    ( --- ) as Incidents
left outer join
    ( --- ) as Requests
    on incidents.group_name = requests.group_name
where 
    requests.group_name is null
Run Code Online (Sandbox Code Playgroud)

这就是同样group_name出现在两行的原因。您可以看到只有在CO没有具有此类值的行但其他表具有时才会发生这种情况。


如果你真的想有 3 个FULL连接,ON条件应该用ISNULL或重写COALESCE

select  
    coalesce(co.group_name, requests.group_Name, incidents.group_Name, 
             problems.group_Name) as [SD Groups]
    ---
from
    ( ---
    ) as CO
full outer join 
    ( ---
    ) as Requests
    on co.group_name = requests.group_name
full outer join
    ( ---
    ) as Problems
    on coalesce(co.group_name, requests.group_name) 
       = problems.group_name
full outer join 
    ( ---
    ) as Incidents
    on coalesce(co.group_name, requests.group_name, problems_group_name) 
       = incidents.group_name
order by 
    --- ;
Run Code Online (Sandbox Code Playgroud)

其他小问题是'single quotes'别名的使用。您应该使用标准"double quotes"或 SQL Server 的[square brackets]. 或者最好不要引用您的标识符,并保持它们没有空格和其他奇怪的字符。单引号字符串应该只用于字符串文字,而不是标识符。