日期:2014-05-17  浏览次数:20575 次

多表查询,如何取并集
有两张表:预算表和实际表,假设预算表中只有 甲产品9月预算数量;实际表有甲产品9、10月份的数据数据,乙产品的9月份实际数据。

客户要求在一张报表中显示9,10月份所有产品的预算、实际、和实际和预算的差额。

上述的例子是预算数据比实际的要少,但是实际情况哪一方数据多,哪一方数据少是未知的,所以用SQL 的left outer Join 查询返回的结果集不准确(部分月份的部分产品查询结果中没有了)。并且我的情况是三张表(预算、ForeCast和实际),两张表和三张表的情况是不是又不一样?

谢谢


------解决方案--------------------
根据楼主的意思 用FULL JOIN比较合适。
------解决方案--------------------

SELECT ISNULL(a.年,b.年) 年,ISNULL(a.月,b.月) 月
,ISNULL(a.预算数量,0) 预算数量
,ISNULL(a.ForeCast数量,0) ForeCast数量
,ISNULL(b.数量,0) 实际数量
--差额計算這裡省略
from
(
SELECT ISNULL(a.年,b.年) 年,ISNULL(a.月,b.月) 月
,ISNULL(a.数量,0) 预算数量
,ISNULL(b.数量,0) ForeCast数量
FROM 预算 a
FULL JOIN ForeCast b ON a.年=b.年 AND a.月=b.月
) a
FULL JOIN 实际 b ON a.年=b.年 AND a.月=b.月

------解决方案--------------------
if OBJECT_ID('tempdb..#预算', 'u') is not null   drop table #预算;
go
create table #预算( [年] int, [月] int, [产品] varchar(100), [数量] INT);
insert #预算
select '2013','9','甲','100' 

if OBJECT_ID('tempdb..#ForeCast', 'u') is not null   drop table #ForeCast;
go
create table #ForeCast([年] int, [月] int, [产品] varchar(100), [数量] INT);
insert #ForeCast
select '2013','9','甲','110' 

if OBJECT_ID('tempdb..#实际', 'u') is not null   drop table #实际;
go
create table #实际([年] int, [月] int, [产品] varchar(100), [数量] INT);
insert #实际
select '2013','9','甲','120' union all
select '2013','9','乙','150' 

--SQL:
SELECT 
年=COALESCE(a.年, b.年),
月=COALESCE(a.月, b.月),
产品=COALESCE(a.产品, b.产品),
a.数量,
[ForeCast数量] = c.数量,
实际数量 = b.数量,
预算实际差额 = b.数量 - a.数量,
Fore实际差额 = c.数量 - a.数量