2016-11-18 2 views
3

Ich habe eine Tabelle ColumnsWie Zeilen in Spalten in Sql konvertieren

enter image description here

und eine zweite Tabelle Response, in dem alle Daten gespeichert werden.

enter image description here

Jetzt möchte ich eine SQL-Ansicht erstellen, in dem das Ergebnis wie dieses

sollte enter image description here

ich versucht, mit Dreh

select UserId ,FromDate, ToDate, Project, Comment 
from 
(
    select R.UserId ,R.Text , C.ColumnName 
    from [Columns] C 
    INNER JOIN Response R ON C.Id=R.ColumnId 
) d 
pivot 
(
    max(Text) 
    for ColumnName in (FromDate, ToDate, Project, Comment) 
) piv; 

aber das tat es nicht arbeitete für mich, ich habe auch diese verwiesen, war aber nicht in der Lage, es zu implementieren. Irgendwelche Ideen, wie man dasselbe in SQL View erreicht?

Scripts für die Tabellen:

CREATE TABLE [dbo].[Columns](
    [Id] [bigint] IDENTITY(1,1) NOT NULL, 
    [Name] [nvarchar](1000) NULL, 
    [IsActive] [bit] NULL, 
CONSTRAINT [PK_Columns] PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

insert into [Columns] values('FromDate',1) 
insert into [Columns] values('ToDate',1) 
insert into [Columns] values('Project',1) 
insert into [Columns] values('Comment',1) 

CREATE TABLE [dbo].[Response](
    [Id] [bigint] IDENTITY(1,1) NOT NULL, 
    [UserId] [bigint] NOT NULL, 
    [ColumnId] [bigint] NOT NULL, 
    [Text] [nvarchar](max) NULL, 
    [IsActive] [bit] NULL, 
    CONSTRAINT [PK_Response] PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 
insert into [Response] values(1,1,'1/1/2012',1) 
insert into [Response] values(1,2,'1/2/2012',1) 
insert into [Response] values(1,3,'p1',1) 
insert into [Response] values(1,4,'c1',1) 
insert into [Response] values(2,1,'1/1/2013',1) 
insert into [Response] values(2,2,'1/2/2013',1) 
insert into [Response] values(2,3,'p2',1) 
insert into [Response] values(2,4,'c2',1) 
insert into [Response] values(2,1,'1/1/2014',1) 
insert into [Response] values(2,2,'1/2/2014',1) 
insert into [Response] values(2,3,'p3',1) 
insert into [Response] values(2,4,'c3',1) 
insert into [Response] values(3,1,'1/1/2015',1) 
insert into [Response] values(3,2,'1/2/2015',1) 
insert into [Response] values(3,3,'p4',1) 
insert into [Response] values(3,4,'c4',1) 
+0

Zeigen Sie, was nicht für Sie arbeitete. –

+0

@WEI_DBA: Pivot –

+1

Können Sie die Pivot-Abfrage anzeigen, die Sie versuchten, zu verwenden? –

Antwort

2

Ehrlich gesagt, wenn die Spaltentypen nicht ändern wird, oder Sie brauchen nur einen Teil von ihnen, können Sie sie einfach herausfiltern und dann auf anzuschließen, anstatt einen Dreh schreiben. Ich schrieb es mit einem cte, aber sie könnten genauso leicht Unterabfragen sein:

;with fd as 
(
    select 
     UserID, 
     [Text] as FromDate, 
     row_number() over (partition by userID order by ID) as DEDUP 
    from response 
    where ColumnID = 1 
), 
td as 
(
    select 
     UserID, 
     [Text] as ToDate, 
     row_number() over (partition by userID order by ID) as DEDUP 
    from response 
    where ColumnID = 2 
), 
p as 
(
    select 
     UserID, 
     [Text] as Project, 
     row_number() over (partition by userID order by ID) as DEDUP 
    from response 
    where ColumnID = 3 
), 
c as 
(
    select 
     UserID, 
     [Text] as Comment, 
     row_number() over (partition by userID order by ID) as DEDUP 
    from response 
    where ColumnID = 4 
) 
select 
    fd.*, 
    td.ToDate, 
    p.Project, 
    c.Comment 
from fd 
    inner join td 
     on fd.UserId = td.UserId 
      and fd.DEDUP = td.DEDUP 
    inner join p 
     on fd.UserId = p.UserId 
      and fd.DEDUP = p.DEDUP 
    inner join c 
     on fd.UserId = c.UserId 
      and fd.DEDUP = c.DEDUP 
+0

Ihre Abfrage gibt doppelte Datensätze zurück, gibt es eine Möglichkeit, eindeutige Datensätze zu erhalten. –

+0

@SidM Ich habe meinen Tippfehler korrigiert. lass mich wissen, ob das jetzt richtig funktioniert – DForck42

+0

Nein, es gibt immer noch die doppelte Ergebnisse –

-1

Sie mögen dieses dieses

;with cte as 
(
    select r.*, 
    c.name 
    from Response r 
     inner join Columns c 
      on r.columnid = c.id 
) 
select 
    Userid, 
    max([FromDate]) as [FromDate], 
    max([ToDate]) as [ToDate], 
    max([Project]) as [Project], 
    max([Comment]) as [Comment] 
from cte 
pivot 
(
    max(Text) for name in ([FromDate], [ToDate], [Project], [Comment]) 
) p 
group by userid 
+0

2 Probleme in der Antwort, '1':' max' Funktion gibt null für 'date' Werte zurück, hier für Spalten' FromDate' und 'Todate'. '2': nur 1 Zeile zurückgegeben für' UserId = 2' –

+0

Geben Sie Ihre Eingabe Beispieldaten als Skripte –

+0

freigegeben die Skripte –

0

abfragen kann versuchen. Ich habe an deiner Antwort gearbeitet.

select UserId ,FromDate, ToDate, Project, Comment 
from 
(
    select R.UserId ,R.RText , C.ColumnName 
    from [Columns] C 
    INNER JOIN Response R ON C.Id=R.ColumnId 
) d 
pivot 
(
    Min(Rtext) 
    for ColumnName in (FromDate, ToDate, Project, Comment) 
) piv 

UNION 
select UserId ,FromDate, ToDate, Project, Comment 
from 
(
    select R.UserId ,R.RText , C.ColumnName 
    from [Columns] C 
    INNER JOIN Response R ON C.Id=R.ColumnId 
) d 
pivot 
(
    Max(Rtext) 
    for ColumnName in (FromDate, ToDate, Project, Comment) 
) piv; 
+0

'max' und' min' Funktionen gibt null für Datumstyp Werte zurück, hier für Spalten 'FromDate' und' Todate'. Außerdem berücksichtigen Sie nur zwei Zeilen für die UserId = 2, es kann mehr Zeilen für jede UserId geben –

+0

True. Ich ging basierend auf Ihren Daten. –