SQL Server 2005
我有一个SQL函数(ftn_GetExampleTable),它返回一个包含多个结果行的表
EXAMPLE
ID MemberID MemberGroupID Result1 Result2 Result3 Year Week
1 1 1 High Risk 2 xx 2011 22
2 11 4 Low Risk 1 yy 2011 21
3 12 5 Med Risk 3 zz 2011 25
etc.
现在我在结果2的表格上进行计数和分组,例如我得到
SELECT MemberGroupID, Result2, Count(*) AS ExampleCount, Year, Week
FROM ftn_GetExampleTable
GROUP BY MemberGroupID, Result2, Year, Week
MemberGroupID Result2 ExampleCount Year Week
1 2 4 2011 22
4 1 2 2011 21
5 3 1 2011 25
现在想象一下,当我在2011年第20周和第23周之间绘制这个新表格时,您会看到它不会在此示例中绘制20或23或某些组甚至某些结果,因为它们不在所包含的数据,所以我需要在这个表中插入“假数据”,它具有所有可能性,因此即使计数为0,它们至少也会显示在图表上,这是否有意义?
我想知道最简单和最动态的方式,因为它可能是Result1或Result3我想要Graph on(不同的列类型)。
提前致谢
答案 0 :(得分:2)
您的尺寸看起来像是:MemberGroupID
,Result2
和周(Year
,Week
)。
解决此问题的一种方法是生成所有维度所需的所有值的列表,并生成它们的笛卡尔积。例如,
SELECT m.MemberGroupID, n.Result2, w.Year, w.Week
FROM (SELECT MemberGroupID FROM ftn_GetExampleTable GROUP BY MemberGroupID) m
CROSS
JOIN (SELECT Result2 FROM ftn_GetExampleTable GROUP BY Result2 ) n
CROSS
JOIN (SELECT Year, Week FROM myCalendar WHERE ... ) w
您不一定需要名为myCalendar的表格。 (这种方法似乎确实很受欢迎。)您只需要一个行源,您可以从中获取(年,周)元组列表。 (Stackoverflow中的其他问题有答案,如何生成日期列表。)
MemberGroupID和Result2值的列表不必来自ftn_GetExampleTable rowsource,您可以替换另一个查询。
使用这些尺寸的笛卡尔积,您就拥有了一个完整的网格"。现在,您可以将原始结果集LEFT JOIN加入。
任何你没有来自" gappy"结果查询,您将返回NULL。您可以保留NULL,或者将其替换为0,这可能是您想要的,如果它是"计数"你要回来了。
SELECT d.MemberGroupID
, d.Result2
, d.Year
, d.Week
, IFNULL(r.ExampleCount,0) as ExampleCount
FROM ( <dimension query from above> ) d
LEFT
JOIN ( <original ExampleCount query> ) r
ON r.MemberGroupID = d.MemberGroupID
AND r.Result2 = d.Result2
AND r.Year = d.Year
AND r.Week = d.Week
可以重构该查询以使用公用表表达式,这使得查询更容易阅读,尤其是当您包含多个度量时。
; WITH d AS ( /* <dimension query with no gaps (example above)> */
)
, r AS ( /* <original query with gaps> */
SELECT MemberGroupID, Result2, Count(*) AS ExampleCount, Year, Week
FROM ftn_GetExampleTable
GROUP BY MemberGroupID, Result2, Year, Week
)
SELECT d.*
, IFNULL(r.ExampleCount,0)
FROM d
LEFT
JOIN r
ON r.Year=d.Year AND r.Week=d.Week AND r.MemberGroupID = d.MemberGroupID
AND r.Result2 = d.Result2
这不是解决问题的完整解决方案,但它概述了您可以使用的方法。
答案 1 :(得分:0)
每当我需要在SQL-Server中生成一个序列时,我使用sys.all_objects
表和ROW_NUMBER
函数,然后根据需要对其进行操作:
SELECT ROW_NUMBER() OVER(ORDER BY Object_ID) AS Sequence
FROM Sys.All_Objects
因此,对于我将使用的年份和周数列表:
DECLARE @StartDate DATETIME,
@EndDate DATETIME
SET @StartDate = '20110101'
SET @EndDate = '20120601'
SELECT DATEPART(YEAR, Date) AS YEAR,
DATEPART(WEEK, Date) AS WeekNum
FROM ( SELECT DATEADD(WEEK, ROW_NUMBER() OVER(ORDER BY Object_ID) - 1, @StartDate) AS Date
FROM Sys.All_Objects
) Dates
WHERE Date < @endDate
日期子查询在开始日期和结束日期之间以一周为间隔提供日期列表。
因此,在您的示例中,最终结果将是:
DECLARE @StartDate DATETIME,
@EndDate DATETIME
SET @StartDate = '20110101'
SET @EndDate = '20120601'
;WITH Data AS
( SELECT MemberGroupID,
Result2,
Count(*) AS ExampleCount,
Year,
Week
FROM ftn_GetExampleTable
GROUP BY MemberGroupID, Result2, Year, Week
), Dates AS
( SELECT DATEPART(YEAR, Date) AS YEAR,
DATEPART(WEEK, Date) AS WeekNum
FROM ( SELECT DATEADD(WEEK, ROW_NUMBER() OVER(ORDER BY Object_ID) - 1, @StartDate) AS Date
FROM Sys.All_Objects
) Dates
WHERE Date < @endDate
)
SELECT YearNum,
WeeNum,
MemberID,
Result2,
COALESCE(ExampleCount, 0) AS ExampleCount
FROM Dates
LEFT JOIN Data
ON YearNum = Data.Year
AND WeekNum = Data.Week