2016-11-18 2 views
3

Я за столом ColumnsКак преобразовать строки в Колонном в Sql

enter image description here

и вторую таблицу Response, в котором сохраняются все данные.

enter image description here

Теперь я хочу, чтобы создать SQL View, в котором результат должен быть как этот

enter image description here

Я попытался с помощью шарнира

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; 

но не работал для меня, я также сослался на это Efficiently convert rows to columns in sql server, но не смог его реализовать. Любые идеи о том, как добиться этого в SQL View?

Сценарии для таблиц:

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

Показать, что не сработало для вас. –

+0

@WEI_DBA: Pivot –

+1

Можете ли вы показать сводный запрос, который вы пытались использовать? –

ответ

2

Честно говоря, если типы столбцов не изменится, или вам нужно только подмножество из них, вы могли бы просто фильтровать их, а затем присоединиться на них, а не написать стержень. Я написал это с использованием cte, но они могли бы так же легко быть подзапросами:

;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

ваш запрос возвращает повторяющиеся записи, есть ли способ получить уникальные записи. –

+0

@SidM Я исправил свою опечатку. дайте мне знать, правильно ли это работает сейчас – DForck42

+0

Нет, его все еще дают повторяющиеся результаты –

-1

Вы можете запросить как этот

;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 проблемы в ответе, '1':' max' возвращает значение null для значений типа date, здесь для столбцов 'FromDate' и' Todate'. '2': только 1 строка, возвращаемая для' UserId = 2' –

+0

. Предоставьте данные вашего образца примера в виде сценариев. –

+0

поделился сценариями –

0

Попробуйте это. Я работал над вашим ответом.

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' и' min' возвращают значение null для значений типа даты, здесь для столбцов 'FromDate' и' Todate'. Также вы рассматриваете только две строки для UserId = 2, может быть больше строк для любого UserId –

+0

True. Я основывался на ваших данных. –

Смежные вопросы