对于您的下一个问题,我会要求您创建一个 MCVE 来重现您的问题。最少是一些样本数据,最好以 DDL 和 DML 的形式提供。
这次我为你做了这件事。这不是您的确切问题,但它将有助于演示该方法。
首先,我们需要一个带有一些数据的模型表:
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 | 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 |
+---------+--------+------------------------+-------------------------+-------------------------+
您可以看到,每个 GroupId 被提及的频率与有数据的频率一样高。第 1 组用 3 行 x、y 和 z 表示,而第 2 组用 z 和 x 表示,第 3 组只用 y 表示。
您需要的是一个固定的集合,其中包含您在任何情况下都希望看到的所有行。如果您可以确定您想要查看的任何组合在您的集合中至少存在一次,您可以直接从数据中提取它,否则您必须维护一个提供此类修复集的表。在我假设的示例中,现有数据可以提供我需要的所有内容。
--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 |
+---------+--------+------------------------+-------------------------+-------------------------+
更新
我试图修复您的查询,但我无法对其进行测试。所以这是在半夜蒙着眼睛飞过茂密的森林;-)
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;
我用易于维护的表替换了您的单个临时表。检查注释掉的 SELECT 看看会发生什么......
我又引入了一个 CTE 来将您的聚合/计算与旋转的LEFT JOIN
.
祝你好运。如果这不起作用,请以消耗性格式提供样本数据,减少到所需的最低限度...