2

我有几个看起来像这样的表 表 1

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

ETC..

表 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

ETC..

event_code 将替换为位于另一个表中的事件的实际描述,但我想我会先看看它是如何工作的。

一些列标题将是静态的,而其他列标题将基于日期创建。有谁知道我如何使用 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在哪里?

请注意,如果同一个人在一个月内发生了多次事件,则您的示例不会显示您希望如何处理。此示例仅采用该月的最后一个事件。

于 2009-05-30T08:24:33.823 回答
0

你想转 http://msdn.microsoft.com/en-us/library/ms177410.aspx

于 2009-05-29T14:18:30.337 回答
0

这听起来像是一个报告任务。报告,通常从数据库的角度被称为 OLAP,在线分析处理,往往与“传统”数据库访问,OLTP(在线事务处理)有很大不同,因为它通常由跨越更长时期的大量数据聚合组成的时间。很多时候,您正在寻找的那种聚合。

使用 Tetraneutron 建议的 Pivot 对于较小的数据集就足够了。但是,随着您需要报告的数据量的增长,您可能需要更高级的东西。OLAP 由 SQL Server Analysis Services (SSAS) 提供,于 2005 年和 2008 年可用。使用 SSAS,您可以创建多维数据存储库,这些存储库可以直接从 OLTP 数据库或从中间数据仓库数据库预聚合数据。多维数据(通常称为多维数据集)提供了一种更快的方式来访问可以从 Pivot 获取的数据类型,而不会影响 OLTP 数据库中标准事务处理的性能。

如果您需要报告的数据多于少量,我建议您查看 SQL Server Analysis Services 2005、OLAP、Cubes 和 MDX(T-SQL 的多维扩展)。有一个更大的学习曲线需要设置建立一个 OLAP 多维数据集,但一旦设置好,如果您有大量的报告需求,拥有一个多维数据集的好处可能是巨大的。

于 2009-05-29T14:32:39.543 回答
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 回答