2010-03-08 10 views
2

J'ai une page qui construit dynamiquement des champs de saisie de formulaires à partir d'une table permettant aux utilisateurs d'entrer des entrées dans le formulaire. Chaque entrée est un champ dans une table _info.transformation de table horizontale à verticale dans SQL Server 2005

Je voudrais rapport montrant toutes les entrées d'un utilisateur dans une ligne. Chaque entrée de champ est une ligne. J'ai donc besoin de prendre les données verticales et de les rendre horizontales. Il existe de nombreuses formes différentes avec des configurations différentes, elles doivent donc être dynamiques. J'ai trouvé beaucoup d'articles pour les pivots de tableau croisé, mais ils ne fonctionnent que pour les aggragates/sommes.

La table Registration_Info a plusieurs entrées pour une soumission de formulaire. Je dois énumérer ces horazontal avec chaque form_field.label comme nom de champ pour signaler.

Ci-dessous est une mise en page de table exemple:

FORM 
—————————————— 
FORM_ID|FORM_NAME 
500|“Custom Form 1″ 

FORM_FIELD 
—————————————— 
FORM_FIELD_ID|FORM_ID|LABEL 
1|500|“Field 1″ 
2|500|“Field 2″ 

REGISTRATION 
—————————————— 
REG_ID|FORM_ID|USER_ID 
23|500|45 
24|500|98 

REGISTRATION_INFO 
—————————————— 
REG_ID|FORM_FIELD_ID|FIELD_VALUE 
23|1|“My Name” 
24|2|“My City” 

Required Report Output: 
REG_ID |Field 1 |Field 2 |FORM_ID |USER_ID 
——————————————————————————————— 
23 |My Name |My City |500 |45 
24 |Another Name |Another City |500 |98 

Répondre

2

Je crois que cela résoudra vos besoins:

STATIC PIVOT

create table #form 
(
    form_id int, 
    form_name varchar(50) 
) 
create table #form_field 
(
    form_field_id int, 
    form_id int, 
    label varchar(50) 
) 
create table #registration 
(
    reg_id int, 
    form_id int, 
    userid int 
) 
create table #registration_info 
(
    reg_id int, 
    form_field_id int, 
    field_value varchar(50) 
) 

insert into #form values(500, 'Custom Form 1') 
insert into #form_field values(1, 500, 'Field 1') 
insert into #form_field values(2, 500, 'Field 2') 
insert into #registration values(23, 500, 45) 
insert into #registration values(24, 500, 98) 
insert into #registration_info values(23, 1, 'My Name') 
insert into #registration_info values(24, 2, 'My City') 


select r.reg_id 
    , IsNull(p.[Field 1], '') as Field1 
    , IsNull(p.[Field 2], '') as Field2 
    , r.form_id 
    , r.userid 
from 
(
    select ri.reg_id 
     , ri.field_value 
     , ff.form_id 
     , ff.label 
    from #registration_info ri 
    inner join #form_field ff 
     on ri.form_field_id = ff.form_field_id 
) riff 
pivot 
(
    max(field_value) 
    for label in ([Field 1], [Field 2]) 
) p 
JOIN #registration r 
    on p.form_id = r.form_id 
    AND p.reg_id = r.reg_id 

Voici une sqlfiddle avec une version de travail.

PIVOT DYNAMIC Cette version obtenir la liste du champ d'abord, puis les faire pivoter.

create table form 
(
    form_id int, 
    form_name varchar(50) 
) 
create table form_field 
(
    form_field_id int, 
    form_id int, 
    label varchar(50) 
) 
create table registration 
(
    reg_id int, 
    form_id int, 
    userid int 
) 
create table registration_info 
(
    reg_id int, 
    form_field_id int, 
    field_value varchar(50) 
) 

insert into form values(500, 'Custom Form 1') 
insert into form_field values(1, 500, 'Field 1') 
insert into form_field values(2, 500, 'Field 2') 
insert into registration values(23, 500, 45) 
insert into registration values(24, 500, 98) 
insert into registration_info values(23, 1, 'My Name') 
insert into registration_info values(24, 2, 'My City') 

DECLARE @cols AS VARCHAR(MAX), 
    @query AS VARCHAR(MAX); 

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.label) 
      FROM dbo.form_field c 
      FOR XML PATH(''), TYPE 
      ).value('.', 'VARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT r.reg_id, ' + @cols + ', r.form_id, r.userid from 
      (
       select ri.reg_id 
        , ri.field_value 
        , ff.form_id 
        , ff.label 
       from registration_info ri 
       inner join form_field ff 
        on ri.form_field_id = ff.form_field_id 
      ) riff 
      pivot 
      (
       max(field_value) 
       for label in (' + @cols + ') 
      ) p 
      JOIN registration r 
       on p.form_id = r.form_id 
       AND p.reg_id = r.reg_id' 


execute(@query) 
+0

Probablement besoin de rendre le résultat final SQL dynamique car le nombre de colonnes pivot sera inconnu. Boucle à travers les champs pour le formulaire spécifié, puis ajouter dans les colonnes pivot. Pivot est la voie à suivre pour la solution générique. – ulty4life

+0

@ ulty4life Vous avez probablement raison, j'ai mis à jour ma réponse pour inclure un PIVOT SQL dynamique. – Taryn