2

この表1のようなテーブルがいくつかあります

user_id   |  name
-------------------------   
x111      |   Smith, James
x112      |   Smith, Jane

等..

表 2

id    |   code    |    date       |  incident_code    | user_id
-----------------------------------------------------------------
1     |    102008 |   10/20/2008  |    1              | x111
2     |    113008 |   11/30/2008  |    3              | x111
3     |    102008 |   10/20/2008  |    2              | x112
4     |    113008 |   11/30/2008  |    5              | x112 

私が表示したいのは、このようなものです

user_id     |    user_name    |   INCIDENT IN OCT 2008   | INCIDENT IN NOV 2008
------------------------------------------------------------------------------ 
x111        |    Smith, John  |   1                      | 3
x112        |    Smith, Jane  |   2                      | 5

等..

インシデントコードは、別のテーブルにあるインシデントの実際の説明に置き換えられますが、これがどのように機能するかを最初に確認したいと思いました。

列ヘッダーには静的なものもあれば、日付に基づいて作成されるものもあります。SQL Server 2005を使用してこれを行う方法を知っている人はいますか? いくつかの例は非常に役立ちます。

前もって感謝します

4

4 に答える 4

2

PIVOT を使用して動的 SQL を生成して実行するソリューションを次に示します。

DECLARE @pivot_list AS VARCHAR(MAX)

--
;
WITH    cols
          AS ( SELECT DISTINCT
                        'INCIDENT IN ' + LEFT(UPPER(CONVERT(VARCHAR, [date], 107)),
                                              3) + ' '
                        + SUBSTRING(UPPER(CONVERT(VARCHAR, [date], 107)), 9, 4) AS col
               FROM     so926209_2
             )
    SELECT  @pivot_list = COALESCE(@pivot_list + ', ', '') + '[' + col + ']'
    FROM    cols

--
DECLARE @template AS VARCHAR(MAX)
SET @template = 'WITH incidents AS (
SELECT  [user_id],
        incident_code,
        ''INCIDENT IN '' + LEFT(UPPER(CONVERT(VARCHAR, [date], 107)), 3)
        + '' '' + SUBSTRING(UPPER(CONVERT(VARCHAR, [date], 107)), 9, 4) AS col
FROM    so926209_2
)
,results AS (
SELECT * FROM incidents PIVOT (MAX(incident_code) FOR col IN ({@pivot_list})) AS pvt
)
SELECT results.[user_id]
    ,so926209_1.[name]
    ,{@select_list}
FROM results INNER JOIN so926209_1 ON so926209_1.[user_id] = results.[user_id]
'

DECLARE @sql AS VARCHAR(MAX)
SET @sql = REPLACE(REPLACE(@template, '{@pivot_list}', @pivot_list), '{@select_list}', @pivot_list)

--PRINT @sql
EXEC (@sql)

どこso926209_1に、so926209_2あなたのテーブル 1 とテーブル 2

同じ人物に対して 1 か月に複数のインシデントが発生した場合、この例ではそれをどのように処理するかが示されていないことに注意してください。この例では、その月の最後のインシデントのみを取得します。

于 2009-05-30T08:24:33.823 に答える
0

これはレポートタスクのように聞こえます。データベースの観点からOLAP(オンライン分析処理)と呼ばれることが多いレポートは、「従来の」データベースアクセスであるOLTP(オンライントランザクション処理)とはかなり頻繁に異なる傾向があり、より長い期間にわたるデータの大規模な集約で構成されることがよくあります。時間の。かなり頻繁に、あなたが探している種類の集合体。

テトラニュートロンが提案するピボットの使用は、より小さなデータセットには十分です。ただし、レポートする必要のあるデータの量が増えるにつれて、より高度なものが必要になる場合があります。OLAPは、2005年と2008年に利用可能なSQL Server Analysis Services(SSAS)によって提供されます。SSASを使用すると、OLTPデータベースから直接、または中間データウェアハウスデータベースからデータを事前に集約する多次元データリポジトリを作成できます。多次元データ(通常はキューブと呼ばれます)は、OLTPデータベースでの標準のトランザクション処理のパフォーマンスを妨げることなく、ピボットから取得できる種類のデータにアクセスするためのはるかに高速な方法を提供します。

レポートする必要のあるデータが少なすぎる場合は、SQL Server Analysis Services 2005、OLAP、キューブ、およびMDX(T-SQLの多次元拡張機能)を確認することをお勧めします。設定する学習曲線は大きくなります。 OLAPキューブを作成しますが、一度設定すると、重要なレポートのニーズがある場合に、OLAPキューブを使用することのメリットは非常に大きくなる可能性があります。

于 2009-05-29T14:32:39.543 に答える
0

ピボットしたい http://msdn.microsoft.com/en-us/library/ms177410.aspx

于 2009-05-29T14:18:30.337 に答える
0

次のようなクエリが機能します。

select
    u.User_id,
    u.Name,
    Okt2008Sum = sum(case when i.date between 
        '2008-10-01' and '2008-11-01' then 1 else 0 end),
    Nov2008Sum = sum(case when i.date between 
        '2008-11-01' and '2008-12-01'then 1 else 0 end)
from #incidents i
inner join #users u on i.user_id = u.user_id
group by u.user_id, u.name

クライアントとそれを実行する必要がある頻度に応じて、このクエリを生成できます。SQL では、これは次のようになります。

create table #months (
    MonthName varchar(25),
    StartDate datetime
)

insert into #months values ('Okt2008','2008-10-01')
insert into #months values ('Nov2008','2008-11-01')

declare @query varchar(8000)
select @query = 'select u.User_id, u.Name '

select @query = @query + ', ' + MonthName + 
    ' = sum(case when i.date between ''' + cast(StartDate as varchar) + 
    ''' and ''' + cast(dateadd(m,1,StartDate) as varchar) + 
    ''' then 1 else 0 end) '
from #Months

select @query = @query + '
    from #incidents i
    inner join #users u on i.user_id = u.user_id
    group by u.user_id, u.name'

exec (@query)
于 2009-05-29T17:11:21.670 に答える