使用Graphing Purposes的数据填充SQL表

时间:2012-06-22 07:40:37

标签: sql tsql sql-server-2005 function

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(不同的列类型)。

提前致谢

2 个答案:

答案 0 :(得分: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 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