我一直在使用SQL黑客强制空组等,但我已经厌倦了这样做,我想要一个表示层问题的表示层解决方案。我使用SQL / SSRS 2008 R2,遇到越来越多的情况,如下面的情况。
我有日期的专栏组,我有一个工作状态(已取消或未取消)和状态的行组。当我有一天没有工作或一个月没有取消某种类型时,我的问题就出现了。我的要求声明必须修复报表布局,并且这些行/列必须仍然存在,但只是状态0.更糟糕的是,一个作业状态(已取消)的不同状态的数量本身是动态的,并从表中拉出,但是,其他工作状态(未取消)的状态数是固定的。
我的问题是,我可以形成此报告布局:
http://i.stack.imgur.com/0UNZU.jpg
从这些数据集?:
http://i.stack.imgur.com/zsqNw.jpg
- 在SSRS中还是我不得不继续使用SQL技巧来强制进行布局?
答案 0 :(得分:0)
我知道这个问题已经很久了,如果不是你,我希望这个答案可以帮助别人。
根据您所写的内容,您需要的是Common Table Expressions和pivot table dynamic columns。
以下是代码:
--
-- We create the needed schemas and fill them with your data.
--
CREATE TABLE Jobs(Date DATE, State NVARCHAR(32), Status NVARCHAR(32));
CREATE TABLE CancellationTypes (State NVARCHAR(32), Reasons NVARCHAR(32));
--
-- Added the Status column so we can get the cancellation types before
-- the jobs. This way we can get the zeros you need.
--
INSERT INTO CancellationTypes VALUES('Cancelled', 'Weather');
INSERT INTO CancellationTypes VALUES('Cancelled', 'Equipment Failure');
INSERT INTO CancellationTypes VALUES('Cancelled', 'Staff Caused');
INSERT INTO CancellationTypes VALUES('Cancelled', 'Misc');
INSERT INTO CancellationTypes VALUES('Not Cancelled', 'Completed');
INSERT INTO CancellationTypes VALUES('Not Cancelled', 'Partially Completed');
--
-- No changes here...
--
INSERT INTO Jobs VALUES('20140301', 'Cancelled', 'Weather');
INSERT INTO Jobs VALUES('20140301', 'Cancelled', 'Weather');
INSERT INTO Jobs VALUES('20140301', 'Cancelled', 'Equipment Failure');
INSERT INTO Jobs VALUES('20140301', 'Not Cancelled', 'Completed');
INSERT INTO Jobs VALUES('20140302', 'Not Cancelled', 'Completed');
INSERT INTO Jobs VALUES('20140302', 'Not Cancelled', 'Partially Completed');
INSERT INTO Jobs VALUES('20140305', 'Cancelled', 'Weather');
INSERT INTO Jobs VALUES('20140305', 'Cancelled', 'Equipment Failure');
INSERT INTO Jobs VALUES('20140305', 'Cancelled', 'Staff Caused');
INSERT INTO Jobs VALUES('20140305', 'Not Cancelled', 'Completed');
INSERT INTO Jobs VALUES('20140305', 'Not Cancelled', 'Partially Completed');
DECLARE @Headers NVARCHAR(158), @Query NVARCHAR(4000);
--
-- With the CTE we can get our range of dates and use it to create the
-- columns for the final resultset.
--
DECLARE @StartDate AS DATE = '20140301', @EndDate DATE = '20140305';
WITH Dates AS (
SELECT @StartDate AS Day
UNION ALL
SELECT DATEADD(D, 1, Day) FROM Dates WHERE Day < @EndDate
)
SELECT @Headers = STUFF((SELECT DISTINCT '],[' + CONVERT(VARCHAR(10), Day, 101) FROM Dates ORDER BY '],[' + CONVERT(VARCHAR(10), Day, 101) FOR XML PATH('')), 1, 2, '') + ']';
SET @Query =
'SELECT State, Status, ' + @Headers + ' FROM
(
SELECT
CONVERT(VARCHAR(10), J.Date, 101) AS Date,
CT.State,
CT.Reasons AS Status
FROM CancellationTypes AS CT
-- This can give us cancellation types with 0 jobs.
LEFT JOIN Jobs AS J ON CT.Reasons = J.Status AND CT.State = J.State
) t
PIVOT (COUNT(Date) FOR Date IN (' + @Headers + ')) AS pvt ORDER BY pvt.State'
EXECUTE (@Query);
--
-- We're done here...
--
DROP TABLE Jobs;
DROP TABLE CancellationTypes;
......结果:
State Status 03/01/2014 03/02/2014 03/03/2014 03/04/2014 03/05/2014
------------- ------------------- ----------- ----------- ----------- ----------- -----------
Cancelled Equipment Failure 1 0 0 0 1
Cancelled Misc 0 0 0 0 0
Cancelled Staff Caused 0 0 0 0 1
Cancelled Weather 2 0 0 0 1
Not Cancelled Completed 1 1 0 0 1
Not Cancelled Partially Completed 0 1 0 0 1
希望这有帮助。