我正在使用SQL Server 2014
,并且有以下T-SQL
查询用于数据透视:
SELECT *
FROM
(
SELECT
[PropertyCode],
FORMAT([MTH], 'MMM') AS 'MthTxt',
[FY],
ISNULL((SUM([Revenue])/SUM([GN])),0) AS 'RevByGN',
[Market]
FROM View1
WHERE [MTH] BETWEEN '2018-07-01' AND '2020-06-01'
AND [PropertyCode] = 'ABC'
GROUP BY [PropertyCode], [MTH], [FY], [Market]
) AS SourceTable
PIVOT
(
AVG([RevByGN])
FOR [MthTxt] IN ([Jul], [Aug], [Sep], [Oct], [Nov], [Dec], [Jan], [Feb], [Mar], [Apr], [May], [Jun])
) AS PivotTable
我的问题是重点关注的市场,即中国和俄罗斯。由于没有19-20财年的数据,因此枢轴结果不包括这两个市场的19-20财年行。
如何强制我的数据透视结果包含这些行?
我还希望将NULL
的值显示为0
。
根据Shnugo的解决方案添加我到目前为止所做的事情:
CREATE TABLE #temp_table (
PropertyCode nvarchar(15),
FY nvarchar(10),
Market nvarchar(255)
);
INSERT INTO #temp_table VALUES
('CDM', 'FY 18-19', 'France'),
('CDM', 'FY 18-19', 'United Kingdom'),
('CDM', 'FY 18-19', 'Germany'),
('CDM', 'FY 18-19', 'Reunion'),
('CDM', 'FY 18-19', 'South Africa'),
('CDM', 'FY 18-19', 'Russia'),
('CDM', 'FY 18-19', 'Middle East'),
('CDM', 'FY 19-20', 'France'),
('CDM', 'FY 19-20', 'United Kingdom'),
('CDM', 'FY 19-20', 'Germany'),
('CDM', 'FY 19-20', 'Reunion'),
('CDM', 'FY 19-20', 'South Africa'),
('CDM', 'FY 19-20', 'Russia'),
('CDM', 'FY 19-20', 'Middle East')
;WITH temp1 AS
(
SELECT *
FROM (SELECT [PropertyCode] FROM #temp_table
GROUP BY [PropertyCode]) t1
CROSS JOIN (SELECT [FY] FROM #temp_table
GROUP BY [FY]) t2
CROSS JOIN (SELECT [Market] FROM #temp_table
GROUP BY [Market]) t3
)
SELECT PivotTable.*
FROM
(
SELECT
a.[PropertyCode],
a.[FY],
a.[Market],
ISNULL((SUM(b.[Package Revenue Excl VAT])/SUM(b.[GN])),0) AS 'GADR',
FORMAT(b.[MTH], 'MMM') AS 'MthTxt'
FROM [temp1] a
LEFT JOIN [QueryType2_v06feb2019_TBL] b ON (b.PropertyCode = a.PropertyCode AND b.FY = a.FY AND b.Market = a.Market)
WHERE b.[MTH] BETWEEN '2018-07-01' AND '2020-06-01'
GROUP BY a.[PropertyCode], b.[MTH], a.[FY], a.[Market]
)AS SourceTable
PIVOT
(
AVG([GADR])
FOR [MthTxt] IN ([Jul], [Aug], [Sep], [Oct], [Nov], [Dec], [Jan], [Feb], [Mar], [Apr], [May], [Jun])
) AS PivotTable
仍然无法正常工作,并给出以下结果:
答案 0 :(得分:0)
对于您的下一个问题,我将要求您创建一个MCVE以重现您的问题。最小的是一些样本数据,最好以DDL和DML的形式提供。
这次我为您做了。这不是您的确切问题,但这将有助于演示该方法。
首先,我们需要一个带有一些数据的模型表:
system
-此查询存在您正在谈论的问题:
DECLARE @tbl TABLE(ID INT IDENTITY, GroupID INT, SubId CHAR(1),Sub2Id CHAR(1), SomeValue VARCHAR(100));
INSERT INTO @tbl VALUES
(1,'a','x','a with x is First in 1')
,(1,'b','y','b with y is Second in 1')
,(1,'c','z','c with z is Third in 1')
,(2,'b','x','b with x is First in 2')
,(2,'c','z','c with z is Second in 2')
,(3,'a','y','a with y is First in 3');
结果
SELECT p.*
FROM
(
SELECT tbl.SubId
,tbl.GroupID
,tbl.Sub2Id
,tbl.SomeValue
FROM @tbl tbl
) t
PIVOT
(
MAX(SomeValue) FOR SubId IN(a,b,c)
) p
ORDER BY GroupId,Sub2Id;
您可以看到,每个GroupId的引用次数和数据一样多。第1组以3行x,y和z表示,而第2行以z和x表示,而第3行仅以y表示。
您需要的是一个固定的集合,无论如何您都希望看到所有行。如果可以确定,要查看的任何组合在您的集合中至少存在一次,则可以直接从数据中提取出来,否则必须维护一个提供此类修订集的表。在该示例中,我假设现有数据可以满足我的所有需求。
+---------+--------+------------------------+-------------------------+-------------------------+
| GroupID | Sub2Id | a | b | c |
+---------+--------+------------------------+-------------------------+-------------------------+
| 1 | x | a with x is First in 1 | NULL | NULL |
+---------+--------+------------------------+-------------------------+-------------------------+
| 1 | y | NULL | b with y is Second in 1 | NULL |
+---------+--------+------------------------+-------------------------+-------------------------+
| 1 | z | NULL | NULL | c with z is Third in 1 |
+---------+--------+------------------------+-------------------------+-------------------------+
| 2 | x | NULL | b with x is First in 2 | NULL |
+---------+--------+------------------------+-------------------------+-------------------------+
| 2 | z | NULL | NULL | c with z is Second in 2 |
+---------+--------+------------------------+-------------------------+-------------------------+
| 3 | y | a with y is First in 3 | NULL | NULL |
+---------+--------+------------------------+-------------------------+-------------------------+
您看到,我--Create a combination of all existing Groups *cross joined* with all existing subs.
WITH AllCombinations AS
(
SELECT *
FROM (SELECT GroupID FROM @tbl GROUP BY GroupID) t1
CROSS JOIN (SELECT Sub2Id FROM @tbl GROUP BY Sub2Id) t2
)
SELECT p.*
FROM
(
SELECT tbl.SubId
,combos.GroupID
,combos.Sub2Id
,tbl.SomeValue
FROM AllCombinations combos
LEFT JOIN @tbl tbl ON combos.GroupID=tbl.GroupID AND combos.Sub2Id=tbl.Sub2Id
) t
PIVOT
(
MAX(SomeValue) FOR SubId IN(a,b,c)
) p
ORDER BY GroupId,Sub2Id;
与实际表的组合集。我使用LEFT JOIN
别名而不是combos
来选择值。这样可以确保这些值在结果集中,并显示在数据透视表中。
结果
tbl
我试图解决您的查询,但我无法对其进行测试。因此,这是在半夜蒙着双眼穿过茂密的森林;-)
+---------+--------+------------------------+-------------------------+-------------------------+
| GroupID | Sub2Id | a | b | c |
+---------+--------+------------------------+-------------------------+-------------------------+
| 1 | x | a with x is First in 1 | NULL | NULL |
+---------+--------+------------------------+-------------------------+-------------------------+
| 1 | y | NULL | b with y is Second in 1 | NULL |
+---------+--------+------------------------+-------------------------+-------------------------+
| 1 | z | NULL | NULL | c with z is Third in 1 |
+---------+--------+------------------------+-------------------------+-------------------------+
| 2 | x | NULL | b with x is First in 2 | NULL |
+---------+--------+------------------------+-------------------------+-------------------------+
| 2 | y | NULL | NULL | NULL |
+---------+--------+------------------------+-------------------------+-------------------------+
| 2 | z | NULL | NULL | c with z is Second in 2 |
+---------+--------+------------------------+-------------------------+-------------------------+
| 3 | x | NULL | NULL | NULL |
+---------+--------+------------------------+-------------------------+-------------------------+
| 3 | y | a with y is First in 3 | NULL | NULL |
+---------+--------+------------------------+-------------------------+-------------------------+
| 3 | z | NULL | NULL | NULL |
+---------+--------+------------------------+-------------------------+-------------------------+
我用易于维护的树替换了您的单个临时表。检查注释过的SELECT,看看会发生什么...
我又介绍了一个CTE,以将您的聚合/计算与枢纽CREATE TABLE #propCodes (PropertyCode nvarchar(15));
CREATE TABLE #FYs (FY nvarchar(10));
CREATE TABLE #Markets(Market nvarchar(255));
INSERT INTO #propCodes VALUES('CDM');
INSERT INTO #FYs VALUES('FY 18-19'),('FY 19-20');
INSERT INTO #Markets VALUES
('France'),
('United Kingdom'),
('Germany'),
('Reunion'),
('South Africa'),
('Russia'),
('Middle East'),
('France');
/* Check this to see the *cartesian product*
SELECT *
FROM #propCodes
CROSS JOIN #FYs
CROSS JOIN #Markets;
*/
;WITH temp1 AS
(
SELECT *
FROM #propCodes
CROSS JOIN #FYs
CROSS JOIN #Markets
)
,Aggregated AS
(
SELECT
[PropertyCode],
[FY],
[Market],
ISNULL((SUM([Package Revenue Excl VAT])/SUM([GN])),0) AS 'GADR',
FORMAT([MTH], 'MMM') AS 'MthTxt'
FROM [QueryType2_v06feb2019_TBL]
WHERE [MTH] BETWEEN '2018-07-01' AND '2020-06-01'
GROUP BY [PropertyCode], [MTH], a.[FY], [Market]
)
SELECT PivotTable.*
FROM
(
SELECT *
FROM [temp1] a
LEFT JOIN Aggregated b ON (b.PropertyCode = a.PropertyCode AND b.FY = a.FY AND b.Market = a.Market)
)AS SourceTable
PIVOT
(
AVG([GADR]) FOR [MthTxt] IN ([Jul], [Aug], [Sep], [Oct], [Nov], [Dec], [Jan], [Feb], [Mar], [Apr], [May], [Jun])
) AS PivotTable;
分开。
祝你好运。如果这样做不起作用,请以消耗品格式提供样本数据,并减少到所需的最低数量...