Sql 在数据可能不匹配的地方连接两组数据

Sql 在数据可能不匹配的地方连接两组数据,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有两组数据要合并并同时返回,但是我需要连接的列可能在集合a中有值,而在集合B中没有值,反之亦然,因此左/右连接并不理想 设置A 查询- SELECT o.organisation_id, Count(call_opened) 'opened calls', Format(call_opened, 'MMM-yy')'month name', call_severity FROM call c JOIN us

我有两组数据要合并并同时返回,但是我需要连接的列可能在集合a中有值,而在集合B中没有值,反之亦然,因此左/右连接并不理想

设置A

查询-

SELECT o.organisation_id, 
       Count(call_opened)           'opened calls',
       Format(call_opened, 'MMM-yy')'month name', 
       call_severity 
FROM   call c 
       JOIN users u 
         ON u.user_id = c.user_id 
       JOIN organisation o 
         ON o.organisation_id = u.organisation_id
WHERE  Call_Type = 'FT'
GROUP  BY o.organisation_id, 
          Format(call_opened, 'MMM-yy'), 
          call_severity
SELECT o.organisation_id, 
       Count(call_closed)           'closed calls', 
       Format(call_closed, 'MMM-yy')'month name', 
       call_severity 
FROM   call c 
       JOIN users u 
         ON u.user_id = c.user_id 
       JOIN organisation o 
         ON o.organisation_id = u.organisation_id
WHERE  Call_Type = 'FT'
GROUP  BY o.organisation_id, 
          Format(call_closed, 'MMM-yy'), 
          call_severity
SELECT opened.organisation_id, 
       Isnull(opened.[opened calls],0) 'opened calls',  
       Isnull(closed.[closed calls],0) 'closed calls',  
       opened.[month name], 
       opened.call_severity 
FROM   (SELECT o.organisation_id, 
               Count(call_opened)           'opened calls', 
               Format(call_opened, 'MMM-yy')'month name', 
               call_severity 
        FROM   call c 
               JOIN users u 
                 ON u.user_id = c.user_id 
               JOIN organisation o 
                 ON o.organisation_id = u.organisation_id
        WHERE  Call_Type = 'FT'
        GROUP  BY o.organisation_id, 
                  Format(call_opened, 'MMM-yy'), 
                  call_severity) opened 
       LEFT JOIN (SELECT o.organisation_id, 
                         Count(call_closed)           'closed calls', 
                         Format(call_closed, 'MMM-yy')'month name', 
                         call_severity 
                  FROM   call c 
                         JOIN users u 
                           ON u.user_id = c.user_id 
                         JOIN organisation o 
                           ON o.organisation_id = u.organisation_id
                  WHERE  Call_Type = 'FT'
                  GROUP  BY o.organisation_id, 
                            Format(call_closed, 'MMM-yy'), 
                            call_severity) closed 
         ON opened.organisation_id = closed.organisation_id 
            AND opened.[month name] = closed.[month name] 
            AND opened.call_severity = closed.call_severity
WHERE opened.Call_Severity <> 5
ORDER  BY opened.organisation_id ASC
返回-

organisation_id opened calls    month name  call_severity
BES             1               Apr-12      3
BES             1               Dec-13      3
BES             1               Jun-12      3
BES             1               Mar-12      3
BES             2               Nov-11      3
BES             1               Oct-11      3
设置B

查询-

SELECT o.organisation_id, 
       Count(call_opened)           'opened calls',
       Format(call_opened, 'MMM-yy')'month name', 
       call_severity 
FROM   call c 
       JOIN users u 
         ON u.user_id = c.user_id 
       JOIN organisation o 
         ON o.organisation_id = u.organisation_id
WHERE  Call_Type = 'FT'
GROUP  BY o.organisation_id, 
          Format(call_opened, 'MMM-yy'), 
          call_severity
SELECT o.organisation_id, 
       Count(call_closed)           'closed calls', 
       Format(call_closed, 'MMM-yy')'month name', 
       call_severity 
FROM   call c 
       JOIN users u 
         ON u.user_id = c.user_id 
       JOIN organisation o 
         ON o.organisation_id = u.organisation_id
WHERE  Call_Type = 'FT'
GROUP  BY o.organisation_id, 
          Format(call_closed, 'MMM-yy'), 
          call_severity
SELECT opened.organisation_id, 
       Isnull(opened.[opened calls],0) 'opened calls',  
       Isnull(closed.[closed calls],0) 'closed calls',  
       opened.[month name], 
       opened.call_severity 
FROM   (SELECT o.organisation_id, 
               Count(call_opened)           'opened calls', 
               Format(call_opened, 'MMM-yy')'month name', 
               call_severity 
        FROM   call c 
               JOIN users u 
                 ON u.user_id = c.user_id 
               JOIN organisation o 
                 ON o.organisation_id = u.organisation_id
        WHERE  Call_Type = 'FT'
        GROUP  BY o.organisation_id, 
                  Format(call_opened, 'MMM-yy'), 
                  call_severity) opened 
       LEFT JOIN (SELECT o.organisation_id, 
                         Count(call_closed)           'closed calls', 
                         Format(call_closed, 'MMM-yy')'month name', 
                         call_severity 
                  FROM   call c 
                         JOIN users u 
                           ON u.user_id = c.user_id 
                         JOIN organisation o 
                           ON o.organisation_id = u.organisation_id
                  WHERE  Call_Type = 'FT'
                  GROUP  BY o.organisation_id, 
                            Format(call_closed, 'MMM-yy'), 
                            call_severity) closed 
         ON opened.organisation_id = closed.organisation_id 
            AND opened.[month name] = closed.[month name] 
            AND opened.call_severity = closed.call_severity
WHERE opened.Call_Severity <> 5
ORDER  BY opened.organisation_id ASC
报税表-

organisation_id closed calls    month name  call_severity
BES             2               Aug-13      3
BES             1               Dec-11      3
BES             1               Dec-13      3
BES             1               Mar-12      3
BES             1               Nov-11      3
BES             1               Sep-12      3
organisation_id opened calls    closed calls    month name  call_severity
BES             1               0               Apr-12      3
BES             1               1               Dec-13      3
BES             1               0               Jun-12      3
BES             1               1               Mar-12      3
BES             2               1               Nov-11      3
BES             1               0               Oct-11      3
到目前为止

查询-

SELECT o.organisation_id, 
       Count(call_opened)           'opened calls',
       Format(call_opened, 'MMM-yy')'month name', 
       call_severity 
FROM   call c 
       JOIN users u 
         ON u.user_id = c.user_id 
       JOIN organisation o 
         ON o.organisation_id = u.organisation_id
WHERE  Call_Type = 'FT'
GROUP  BY o.organisation_id, 
          Format(call_opened, 'MMM-yy'), 
          call_severity
SELECT o.organisation_id, 
       Count(call_closed)           'closed calls', 
       Format(call_closed, 'MMM-yy')'month name', 
       call_severity 
FROM   call c 
       JOIN users u 
         ON u.user_id = c.user_id 
       JOIN organisation o 
         ON o.organisation_id = u.organisation_id
WHERE  Call_Type = 'FT'
GROUP  BY o.organisation_id, 
          Format(call_closed, 'MMM-yy'), 
          call_severity
SELECT opened.organisation_id, 
       Isnull(opened.[opened calls],0) 'opened calls',  
       Isnull(closed.[closed calls],0) 'closed calls',  
       opened.[month name], 
       opened.call_severity 
FROM   (SELECT o.organisation_id, 
               Count(call_opened)           'opened calls', 
               Format(call_opened, 'MMM-yy')'month name', 
               call_severity 
        FROM   call c 
               JOIN users u 
                 ON u.user_id = c.user_id 
               JOIN organisation o 
                 ON o.organisation_id = u.organisation_id
        WHERE  Call_Type = 'FT'
        GROUP  BY o.organisation_id, 
                  Format(call_opened, 'MMM-yy'), 
                  call_severity) opened 
       LEFT JOIN (SELECT o.organisation_id, 
                         Count(call_closed)           'closed calls', 
                         Format(call_closed, 'MMM-yy')'month name', 
                         call_severity 
                  FROM   call c 
                         JOIN users u 
                           ON u.user_id = c.user_id 
                         JOIN organisation o 
                           ON o.organisation_id = u.organisation_id
                  WHERE  Call_Type = 'FT'
                  GROUP  BY o.organisation_id, 
                            Format(call_closed, 'MMM-yy'), 
                            call_severity) closed 
         ON opened.organisation_id = closed.organisation_id 
            AND opened.[month name] = closed.[month name] 
            AND opened.call_severity = closed.call_severity
WHERE opened.Call_Severity <> 5
ORDER  BY opened.organisation_id ASC
正如您所看到的,这并没有返回我需要的数据,因为集合B包含集合A中不存在的月份数据

理想情况下,我希望返回的数据如下-

organisation_id opened calls    closed calls    month name  call_severity
BES             1               0               Apr-12      3
BES             1               1               Dec-13      3
BES             1               0               Jun-12      3
BES             1               1               Mar-12      3
BES             2               1               Nov-11      3
BES             1               0               Oct-11      3
BES             0               2               Aug-13      3
BES             0               1               Dec-11      3
BES             0               1               Sep-12      3
我曾考虑过创建一个初始临时表,插入月份值,并在该表上加入结果集,但由于数据跨越到2002年,这会太麻烦和混乱,我想要的是可能的还是需要重新设计我的解决方案

我想这就是调用表中需要的所有数据-

Call_ID     Call_Opened                Call_Closed              Call_Severity   User_id
28000001    2011-10-19 13:13:48.000    2011-11-09 11:47:03.000  3               825
28000002    2011-11-07 10:55:24.000    2012-03-05 08:27:54.000  3               825
28000003    2011-11-21 09:11:49.000    2011-12-19 08:41:36.000  3               825
28000006    2012-03-30 15:11:23.000    2013-08-29 15:51:39.000  3               825
28000007    2012-04-02 11:50:22.000    2013-08-29 15:52:11.000  3               825
28000008    2012-06-25 08:12:39.000    2012-09-28 16:32:08.000  3               825
28000012    2013-12-17 07:41:26.000    2013-12-17 08:58:35.000  3               825
你必须使用union

select organisation_id
, sum(opened_calls) opened_calls
, sum(closed_calls) closed_calls
, month_name 
, call_severity
from (
SELECT o.organisation_id, 
   Count(call_opened)           opened_calls,
   0                            closed_calls,
   Format(call_opened, 'MMM-yy') month_name, 
   call_severity 
FROM   call c 
   JOIN users u 
     ON u.user_id = c.user_id 
   JOIN organisation o 
     ON o.organisation_id = u.organisation_id
WHERE  Call_Type = 'FT'
GROUP  BY o.organisation_id, 
      Format(call_opened, 'MMM-yy'), 
      call_severity
union 
SELECT o.organisation_id, 
   0                            opened_calls
   Count(call_closed)           closed_calls, 
   Format(call_closed, 'MMM-yy') month_name, 
   call_severity 
FROM   call c 
   JOIN users u 
     ON u.user_id = c.user_id 
   JOIN organisation o 
     ON o.organisation_id = u.organisation_id
WHERE  Call_Type = 'FT'
GROUP  BY o.organisation_id, 
      Format(call_closed, 'MMM-yy'), 
      call_severity
)tt
group by organisation_id, month_name, call_severity 
你必须使用union

select organisation_id
, sum(opened_calls) opened_calls
, sum(closed_calls) closed_calls
, month_name 
, call_severity
from (
SELECT o.organisation_id, 
   Count(call_opened)           opened_calls,
   0                            closed_calls,
   Format(call_opened, 'MMM-yy') month_name, 
   call_severity 
FROM   call c 
   JOIN users u 
     ON u.user_id = c.user_id 
   JOIN organisation o 
     ON o.organisation_id = u.organisation_id
WHERE  Call_Type = 'FT'
GROUP  BY o.organisation_id, 
      Format(call_opened, 'MMM-yy'), 
      call_severity
union 
SELECT o.organisation_id, 
   0                            opened_calls
   Count(call_closed)           closed_calls, 
   Format(call_closed, 'MMM-yy') month_name, 
   call_severity 
FROM   call c 
   JOIN users u 
     ON u.user_id = c.user_id 
   JOIN organisation o 
     ON o.organisation_id = u.organisation_id
WHERE  Call_Type = 'FT'
GROUP  BY o.organisation_id, 
      Format(call_closed, 'MMM-yy'), 
      call_severity
)tt
group by organisation_id, month_name, call_severity 

您应该对开放通话/关闭通话使用
UNION ALL
,然后在顶部查询中使用
group
。见下面的模型。 如果您有任何问题,请告诉我

SELECT organisation_id, 
       Isnull(SUM([opened calls]),0) 'opened calls',  
       Isnull(SUM([closed calls]),0) 'closed calls',  
       [month name], 
       call_severity 
FROM   (
---Set A 
SELECT o.organisation_id, 
       Count(call_opened)           'opened calls',
       0 'closed calls',
       Format(call_opened, 'MMM-yy')'month name', 
       call_severity 
FROM   call c 
       JOIN users u 
         ON u.user_id = c.user_id 
       JOIN organisation o 
         ON o.organisation_id = u.organisation_id
WHERE  Call_Type = 'FT'
GROUP  BY o.organisation_id, 
          Format(call_opened, 'MMM-yy'), 
          call_severity


UNION ALL   ---Set B

SELECT o.organisation_id, 
       0  'opened calls',
       Count(call_closed)           'closed calls', 
       Format(call_closed, 'MMM-yy')'month name', 
       call_severity 
FROM   call c 
       JOIN users u 
         ON u.user_id = c.user_id 
       JOIN organisation o 
         ON o.organisation_id = u.organisation_id
WHERE  Call_Type = 'FT'
GROUP  BY o.organisation_id, 
          Format(call_closed, 'MMM-yy'), 
          call_severity
)S

GROUP BY
    organisation_id,
    [month name],
    call_severity

您应该对开放通话/关闭通话使用
UNION ALL
,然后在顶部查询中使用
group
。见下面的模型。 如果您有任何问题,请告诉我

SELECT organisation_id, 
       Isnull(SUM([opened calls]),0) 'opened calls',  
       Isnull(SUM([closed calls]),0) 'closed calls',  
       [month name], 
       call_severity 
FROM   (
---Set A 
SELECT o.organisation_id, 
       Count(call_opened)           'opened calls',
       0 'closed calls',
       Format(call_opened, 'MMM-yy')'month name', 
       call_severity 
FROM   call c 
       JOIN users u 
         ON u.user_id = c.user_id 
       JOIN organisation o 
         ON o.organisation_id = u.organisation_id
WHERE  Call_Type = 'FT'
GROUP  BY o.organisation_id, 
          Format(call_opened, 'MMM-yy'), 
          call_severity


UNION ALL   ---Set B

SELECT o.organisation_id, 
       0  'opened calls',
       Count(call_closed)           'closed calls', 
       Format(call_closed, 'MMM-yy')'month name', 
       call_severity 
FROM   call c 
       JOIN users u 
         ON u.user_id = c.user_id 
       JOIN organisation o 
         ON o.organisation_id = u.organisation_id
WHERE  Call_Type = 'FT'
GROUP  BY o.organisation_id, 
          Format(call_closed, 'MMM-yy'), 
          call_severity
)S

GROUP BY
    organisation_id,
    [month name],
    call_severity

这是一个使用交叉应用的好地方:

SELECT o.organisation_id, 
       SUM(v.is_open) as opened_calls,
       SUM(v.is_close) as closed_calls,
       Format(call_time, 'MMM-yy') as month_name, 
       call_severity 
FROM call c JOIN
     users u 
     ON u.user_id = c.user_id JOIN
     organisation o 
     ON o.organisation_id = u.organisation_id CROSS APPLY
     (VALUES (call_opened, 1, 0 ), 
             (call_closed, 0, 1)
     ) as v(call_time, is_open, is_close)
WHERE Call_Type = 'FT'
GROUP BY o.organisation_id, 
         Format(call_time, 'MMM-yy'), 
         call_severity

这是一个使用交叉应用的好地方:

SELECT o.organisation_id, 
       SUM(v.is_open) as opened_calls,
       SUM(v.is_close) as closed_calls,
       Format(call_time, 'MMM-yy') as month_name, 
       call_severity 
FROM call c JOIN
     users u 
     ON u.user_id = c.user_id JOIN
     organisation o 
     ON o.organisation_id = u.organisation_id CROSS APPLY
     (VALUES (call_opened, 1, 0 ), 
             (call_closed, 0, 1)
     ) as v(call_time, is_open, is_close)
WHERE Call_Type = 'FT'
GROUP BY o.organisation_id, 
         Format(call_time, 'MMM-yy'), 
         call_severity


这些子查询造成了一个相当混乱的查询。然而,我怀疑,您所追求的是一个
完全外部联接
?不过,我会考虑整理一下。我非常怀疑您需要2个子查询来实现这一点。像
FORMAT
这样的函数也会影响查询的性能。
FULL OUTER JOIN
返回的结果与
LEFT JOIN
返回的结果完全相同。您能用可能的值共享您的“call”表结构吗?@DMayuri从call table添加了数据这些子查询造成了相当大的混乱然而,我怀疑您所追求的是一个
完全外部连接
?不过,我会考虑整理一下。我非常怀疑您需要2个子查询来实现这一点。像
FORMAT
这样的函数也会影响查询的性能。
FULL OUTER JOIN
返回的结果与
LEFT JOIN
返回的结果完全相同。您可以用可能的值共享您的“call”表结构吗?@DMayuri从call table添加的数据已打开和关闭调用已打开和关闭调用我的调用表中的闭合列?@WhatstThePoint。不,是打字错误。他们应该有资格清楚地知道他们来自
VALUES()
。我的调用表中的call\u opened和call\u closed列是否打开和关闭?@WhatstThePoint。不,是打字错误。他们应该有资格清楚地知道他们来自
VALUES()
。你的回答很好,并给出了我需要的结果,但是我选择了Gordon的答案,只是因为代码较少没有问题。我理解。有时候,拥有所有的选择是很好的。我喜欢这种方法,因为它易于调试。谢谢你让我知道。你的答案肯定会对经验不足的人更有用,因为
交叉应用
是相当先进的。你的答案很好,给了我所需的结果,但是我选择了Gordon的答案,只是因为代码较少没有问题。我理解。有时候,拥有所有的选择是很好的。我喜欢这种方法,因为它易于调试。谢谢你让我知道。你的回答肯定会对经验不足的人更有用,因为
交叉应用
相当先进