1

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.

ここで、たとえば Result 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 である可能性があるため、最も簡単で最も動的な方法について疑問に思っています(異なる列タイプ)。

前もって感謝します

4

2 に答える 2

2

ディメンションはMemberGroupIDResult2、週 ( YearWeek) のようです。

これを解決する 1 つの方法は、すべてのディメンションに対して必要なすべての値のリストを生成し、それらのデカルト積を生成することです。例として、

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 という名前のテーブルは必ずしも必要ではありません。(そのアプローチは一般的なもののようです。) (Year, Week) タプルのリストを導出できる行ソースが必要なだけです。(日付のリストを生成する方法、Stackoverflow の他の場所に質問への回答があります。)

また、MemberGroupID と Result2 の値のリストは、ftn_GetExampleTable 行ソースから取得する必要はなく、別のクエリに置き換えることができます。

これらの次元のデカルト積を使用すると、完全な「グリッド」が得られます。これで、元の結果セットをそれに 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

これは問題に対する完全な解決策ではありませんが、使用できるアプローチの概要を示しています。

于 2012-06-22T14:02:29.617 に答える
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

日付サブクエリは、開始日と終了日の間で 1 週間間隔で日付のリストを提供します。

したがって、あなたの例では、最終結果は次のようになります。

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
于 2012-06-22T08:24:09.170 に答える