Sql 将多个数据集合并到一个查询中
我有多个疑问:Sql 将多个数据集合并到一个查询中,sql,sql-server,sql-server-2008,tsql,sql-server-2008-r2,Sql,Sql Server,Sql Server 2008,Tsql,Sql Server 2008 R2,我有多个疑问: 1) select Year , Month, Sum(Stores) from ABC ; 2) select Year, Month , Sum(SalesStores) from DEF ; 3) slect Year, Month, Sum(Products) from FGH; 我想要的结果是: Year, Month , Sum(Stores), Sum(SalesStores), Sum(Products) 我尝试使用如下查询进行完全
1) select Year , Month, Sum(Stores) from ABC ;
2) select Year, Month , Sum(SalesStores) from DEF ;
3) slect Year, Month, Sum(Products) from FGH;
我想要的结果是:
Year, Month , Sum(Stores), Sum(SalesStores), Sum(Products)
我尝试使用如下查询进行完全外部联接:
SELECT ISNULL(x.[Year], y.[Year]) AS [Year],
ISNULL(x.[Month], y.[Month]) AS [Month],
x.Sum_Stores,
y.Sum_SalesStores,
z.Sum_products
FROM (select Year , Month, Sum(Stores) AS Sum_Stores from ABC ... GROUP BY [Month]) AS x
FULL OUTER JOIN (select Year, Month , Sum(SalesStores) AS Sum_SalesStores from DEF ... GROUP BY [Month]) AS y
ON x.[Year] = y.[Year] AND x.[Month] = y.[Month]
FULL OUTER JOIN (select Year, Month , Sum(products) AS Sum_products from FGH ... GROUP BY [Month]) AS z
ON y.[Year] = z.[Year] AND y.[Month] = z.[Month]
问题是,ABC只有特定月份的数据,DEF有不同月份的数据,而FGH又有不同月份的数据
当我运行上面的查询时,我得到很多空值和0
是否有人可以纠正我的问题,或者告诉我一个适合我的案例的解决方案。使用union All和group by来代替:
select x,y,z from tableA
UNION
select x,y,z from tableB
UNION
select x,y,z from tableC
select year, month, sum(stores) as sumStores, sum(salesStores) as sumSalesStores, sum(products) as sumProducts
from (
select year, month, stores, salesStores = null, products = null
from ABC
union all
select year, month, stores = null, salesStores, products = null
from DEF
union all
select year, month, stores = null, salesStores = null, products
from FGH
) x
group by year, month;
使用以下方法可能更清晰:-
select
Year,
Month,
sum(Stores) as Stores,
sum(SalesStores) as SalesStores,
sum(products) as products
from (
select Year, Month, Stores, 0.00 as SalesStores, 0.00 as products
from ABC ...
union all
select Year, Month, 0 as Stores, SalesStores, 0 as products
from DEF ...
union all
select Year, Month, 0 as Stores, 0 as SalesStores, products
from FGH ...
) source
group by Year, Month
派生表中的第一个
select
语句定义了它的结构,您可能需要将该语句中的占位符列转换为正确精度和比例的类型,以允许后续union
中的数据不丢失任何精度。这里是获取此信息的另一种方法。此示例有一个简短的设置,用于演示此解决方案的实际效果
CREATE TABLE #ABC([Year] INT, [Month] INT, Stores INT);
CREATE TABLE #DEF([Year] INT, [Month] INT, SalesStores INT);
CREATE TABLE #GHI([Year] INT, [Month] INT, Products INT);
INSERT #ABC VALUES (2013,1,1);
INSERT #ABC VALUES (2013,1,2);
INSERT #ABC VALUES (2013,2,3);
INSERT #DEF VALUES (2013,1,4);
INSERT #DEF VALUES (2013,1,5);
INSERT #DEF VALUES (2013,2,6);
INSERT #GHI VALUES (2013,1,7);
INSERT #GHI VALUES (2013,1,8);
INSERT #GHI VALUES (2013,2,9);
INSERT #GHI VALUES (2013,3,10);
SELECT
T.[Year]
,T.[Month]
-- select the sum for each year/month combination using a correlated subquery (each result from the main query causes another data retrieval operation to be run)
,(SELECT SUM(Stores) FROM #ABC WHERE [Year]=T.[Year] AND [Month]=T.[Month]) AS [Sum_Stores]
,(SELECT SUM(SalesStores) FROM #DEF WHERE [Year]=T.[Year] AND [Month]=T.[Month]) AS [Sum_SalesStores]
,(SELECT SUM(Products) FROM #GHI WHERE [Year]=T.[Year] AND [Month]=T.[Month]) AS [Sum_Products]
FROM (
-- this selects a list of all possible dates.
SELECT [Year],[Month] FROM #ABC
UNION
SELECT [Year],[Month] FROM #DEF
UNION
SELECT [Year],[Month] FROM #GHI
) AS T;
编辑:
可以根据请求将其封装在参数化存储过程中:
-- Call proc like this
--EXEC [getMyReport]; -- params are not required, these will default to NULL if not specified.
--EXEC [getMyReport] @Year=2013; -- all 2013 data, all months
--EXEC [getMyReport] @Month=1; -- all January data, from all years
--EXEC [getMyReport] @Year=2013, @Month=2; -- Feb 2013 data only.
CREATE PROCEDURE [dbo].[getMyReport]
@Year INT = NULL -- default to NULL, this makes the param optional when you exec the procedure.
,@Month INT = NULL
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT
T.[Year]
,T.[Month]
-- select the sum for each year/month combination using a correlated subquery (each result from the main query causes another data retrieval operation to be run)
,(SELECT SUM(Stores) FROM #ABC WHERE [Year]=T.[Year] AND [Month]=T.[Month]) AS [Sum_Stores]
,(SELECT SUM(SalesStores) FROM #DEF WHERE [Year]=T.[Year] AND [Month]=T.[Month]) AS [Sum_SalesStores]
,(SELECT SUM(Products) FROM #GHI WHERE [Year]=T.[Year] AND [Month]=T.[Month]) AS [Sum_Products]
FROM (
-- this selects a list of all possible dates.
SELECT [Year],[Month] FROM #ABC
UNION
SELECT [Year],[Month] FROM #DEF
UNION
SELECT [Year],[Month] FROM #GHI
) AS T
WHERE
-- if the param IS NULL, then it will not apply filtering
-- if the param is specified, then it will filter by year or month
(@Year IS NULL OR T.[Year]=@Year)
AND
(@Month IS NULL OR T.[Month]=@Month)
;
END
GO
以下是使用完全联接的答案:
select
coalesce(ABC.Year,DEF.Year,FGH.Year) as Year
,coalesce(ABC.Month,DEF.Month,FGH.Month) as Month
,ABC.Stores
,DEF.SalesStores
,FGH.Products
from (
select Year , Month, Sum(Stores) as Stores from ABC group by Year , Month
) ABC
full join (
select Year, Month , Sum(SalesStores) as SalesStores from DEF group by Year , Month
) DEF
on DEF.year = ABC.Year
and DEF.Month = ABC.Month
full join (
select Year, Month, Sum(Products) as Products from FGH group by Year , Month
) FGH
on (FGH.year = ABC.Year
and FGH.Month = ABC.Month)
or (FGH.Month = DEF.Year
and FGH.Month = DEF.Month)
您可以像这样合并多个集合:
SELECT Year, Month, 'Stores' AS Src, Stores AS Value FROM ABC
UNION ALL
SELECT Year, Month, 'SalesStores', SalesStores FROM DEF
UNION ALL
SELECT Year, Month, 'Products', Products FROM FGH
然后,使用聚合对它们进行排序:
SELECT
Year,
Month,
Stores,
SalesStores,
Products
FROM (
SELECT Year, Month, 'Stores', Stores FROM ABC
UNION ALL
SELECT Year, Month, 'SalesStores', SalesStores FROM DEF
UNION ALL
SELECT Year, Month, 'Products', Products FROM FGH
) AS s (Year, Month, Src, Value)
PIVOT (
SUM(Value) FOR Src IN (Stores, SalesStores, Products)
) AS p
;
或者,首先聚合结果,然后合并聚合集,然后透视,可能更有效:
SELECT
Year,
Month,
Stores,
SalesStores,
Products
FROM (
SELECT Year, Month, 'Stores', SUM(Stores) FROM ABC
UNION ALL
SELECT Year, Month, 'SalesStores', SUM(SalesStores) FROM DEF
UNION ALL
SELECT Year, Month, 'Products', SUM(Products) FROM FGH
) AS s (Year, Month, Src, Value)
PIVOT (
MAX(Value) FOR Src IN (Stores, SalesStores, Products)
) AS p
;
由于PIVOT语法要求使用聚合函数,因此我们可以使用一个只保留已聚合值的函数(在本例中为MAX)。您的代码不包含
UNION
。感谢您的更正,DEF中的完整外部联接选择年、月、和(SalesStores)不应执行。您是否缺少分组依据?我在原始查询中确实有分组依据。我想我会简化它,并且没有添加“按月分组”您的完全加入查询就在不远处了。我没有看到已经有了答案,所以我添加了一个工作示例供您参考。注意第三个表的join子句中的coalesce
而不是isnull
和或。嘿,谢谢,我有两个独立的列Year&Month,而不是date(MyDate)。。你能告诉我我需要如何修改你的查询才能在我的情况下工作吗?修改后的答案使用年和月作为独立的整型字段。太好了!!有没有办法让我通过一个月又一年的辩论,直到那个月才看到结果??现在它显示一年中所有月份的数据+1并标记为答案。很好,如果性能很重要,您可能想尝试我的版本,因为它只会在表中出现一次,它可能会运行得稍微快一点。