我有多个查询:
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。
任何人都可以纠正我对查询的错误或告诉我一个适合我案例的解决方案。
答案 0 :(得分:1)
以下是获取此信息的另一种方法。此示例有一个简短的设置来演示此解决方案的实际效果。
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
答案 1 :(得分:0)
select x,y,z from tableA
UNION
select x,y,z from tableB
UNION
select x,y,z from tableC
答案 2 :(得分:0)
使用union alls和group by来代替:
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;
答案 3 :(得分:0)
使用类似的方法可能更清楚: -
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
语句定义了它的结构 - 您可能需要cast
该语句中的占位符列,以获得正确精度和比例的类型,以允许后续数据{ {1}}不会失去任何精确度。
答案 4 :(得分:0)
以下是使用完整联接的答案:
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)
答案 5 :(得分:0)
您可以将多个集合合并为:
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
然后PIVOT他们聚合:
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
;
或者首先聚合结果可能更有效,然后联合聚合集,然后PIVOT:
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)。