Sql 在数据可能不匹配的地方连接两组数据
我有两组数据要合并并同时返回,但是我需要连接的列可能在集合a中有值,而在集合B中没有值,反之亦然,因此左/右连接并不理想 设置A 查询-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
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的答案,只是因为代码较少没有问题。我理解。有时候,拥有所有的选择是很好的。我喜欢这种方法,因为它易于调试。谢谢你让我知道。你的回答肯定会对经验不足的人更有用,因为交叉应用
相当先进