Question

J'ai deux ou trois tableaux qui ressemblent à ce Tableau 1

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

etc ..

Tableau 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 

Qu'est-ce que je voudrais afficher est quelque chose comme ceci

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

etc ..

Le incident_code serait remplacé par la description réelle de l'incident qui est situé dans une autre table, mais je pensais que je verrais comment cela fonctionnerait d'abord.

Certains des en-têtes de colonne serait statique tandis que d'autres seraient créés en fonction de la date. Quelqu'un at-on savoir comment je peux le faire en utilisant le serveur SQL 2005? Quelques exemples seraient très utiles.

Merci d'avance

Était-ce utile?

La solution

Voici une solution qui génère et exécute le SQL dynamique avec un PIVOT:

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 sont vos tableaux 1 et 2

Notez que si vous avez plusieurs incidents dans un mois pour la même personne, votre exemple ne montre pas comment vous voulez que manutentionnés. Cet exemple ne prend que le dernier incident au cours du mois.

Autres conseils

Cela ressemble à une tâche de reporting. De rapports, souvent appelé dans une perspective de base de données OLAP, Aanalytical traitement en ligne, a tendance à varier assez souvent d'un accès base de données « traditionnelle », OLTP (Online Transaction Processing) en ce qu'il est assez souvent composé de grandes agrégations de données couvrant des périodes plus de temps. Très souvent, le genre d'agrégation votre recherche.

Utilisation d'un pivot comme suggéré tétraneutron sera suffisant pour les ensembles de données plus petits. Cependant, comme le volume de données que vous devez faire rapport sur grandit, vous devrez peut-être quelque chose de plus avancé. OLAP est fourni par SQL Server Analysis Services (SSAS), disponible en 2005 et 2008. En utilisant SSAS, vous pouvez créer des référentiels de données multidimensionnelles que les données pré-agrégées à partir soit une base de données OLTP directement, ou à partir d'une base de données de l'entrepôt de données intermédiaire. les données multidimensionnels (généralement appelés cubes), fournissent un moyen d'accéder beaucoup plus rapidement le genre de données que vous pouvez obtenir à partir d'un pivot, sans interférer avec les performances de traitement des transactions standard dans votre base de données OLTP.

Si vous avez plus d'une petite quantité de données que vous devez faire rapport sur, je vous recommande vérifier SQL Server Analysis Services 2005, OLAP, cubes, et MDX (extensions multidimensionnels pour T-SQL.) Il y a un learnig plus courbe de mettre en place un cube OLAP, mais une fois qu'il est mis en place, les avantages d'avoir peut être énorme si vous avez des besoins de rapports importants.

Une requête comme ceci fonctionnerait:

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

En fonction de votre client et la fréquence à laquelle vous devez exécuter, vous pouvez générer cette requête. Dans SQL cela ressemblerait à ceci:

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)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top