2012-06-22 8 views
1

SQL Server 2005的焊點OUT與數據的SQL表圖形用途

我有一個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我想繪製(不同的列類型)。

在此先感謝

回答

2

它看起來像你的尺寸是:MemberGroupIDResult2和周(YearWeek)。

解決此問題的一種方法是生成所有維的所有值的列表,並生成它們的笛卡爾乘積。作爲示例,

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行源,您可以替換另一個查詢。

有了這些尺寸的笛卡爾積,你就有了一個完整的「網格」。現在您可以左鍵加入您的原始結果集。

任何你沒有從「gappy」結果查詢中找到匹配行的地方,你都會返回一個NULL。你可以保留NULL,或者用0替換它,如果它是你正在返回的「count」,這可能就是你想要的。

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 

這不是您的問題的完整工作解決方案,但它概述了您可以使用的方法。

+0

謝謝Spencer,我對這個概念有了一個發揮,現在它正在返回我想要的,很好的方法,謝謝。 – Coesy

0

每當我需要生成SQL-Server中的順序我用的是sys.all_objects表與ROW_NUMBER功能一起使用,那麼maninpulate它要求:

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