2013-05-28 3 views
0

Я пытаюсь создать динамическую сводную таблицу для получения результатов в разных столбцах, а не в строках.Динамические сводные таблицы MS SQL 2008

Это таблица, я использую для тестирования

CREATE TABLE [dbo].[Authors](
[Client_Id] [nvarchar](50) NOT NULL, 
[Project_Id] [nvarchar](50) NOT NULL, 
[Person_Id] [int] NOT NULL, 
[Author_Number] [int] NOT NULL, 
[Family_Name] [nvarchar](50) NULL, 
[First_Name] [nvarchar](50) NULL, 
) 

INSERT INTO Authors (Client_Id, Project_Id, Person_Id, Author_Number, Family_Name, First_Name) 
VALUES ('TEST','TEST',12345,1,'Giust','Fede') 
INSERT INTO Authors (Client_Id, Project_Id, Person_Id, Author_Number, Family_Name, First_Name) 
VALUES ('TEST','TEST',12345,2,'Giust','Fede') 
INSERT INTO Authors (Client_Id, Project_Id, Person_Id, Author_Number, Family_Name, First_Name) 
VALUES ('TEST','TEST',12346,1,'Giust','Fede') 
INSERT INTO Authors (Client_Id, Project_Id, Person_Id, Author_Number, Family_Name, First_Name) 
VALUES ('TEST','TEST',12346,2,'Giust','Fede') 
INSERT INTO Authors (Client_Id, Project_Id, Person_Id, Author_Number, Family_Name, First_Name) 
VALUES ('TEST','TEST',12346,3,'Giust','Fede') 

До сих пор я получаю результаты как этот

CLIENT_ID PROJECT_ID PERSON_ID AUTHOR_NUMBER FAMILY_NAME FIRST_NAME 
TEST  TEST  12345  1    Giust  Fede 
TEST  TEST  12345  2    Ma   Ke 
TEST  TEST  12346  1    Jones  Peter 
TEST  TEST  12346  2    Davies  Bob 
TEST  TEST  12346  3    Richards  Craig 

Мне нужны результаты, чтобы выйти, как это, и быть динамичным потому что когда-нибудь у меня могут быть 2 автора или 10 авторов.

CLIENT_ID PROJECT_ID PERSON_ID FAMILY_NAME_1 FIRST_NAME_1 FAMILY_NAME_2 FIRST_NAME_2  FAMILY_NAME_3 FIRST_NAME_3  
TEST  TEST  12345  Giust   Fede   Ma    Ke 

TEST  TEST  12346  Jones   Peter   Davies   Bob     Richards   Craig 

Я пытался использовать этот код, но постоянно получаю ошибки

SQL Fiddle

ответ

0

Вот несколько предложений, чтобы решить вашу проблему.

Во-первых, ваш текущий код не содержит всех столбцов в таблице, вам нужно только UNPIVOT столбцам Family_Name и First_Name. В результате я бы не использовал переменную, чтобы получить этот список столбцов, просто скопируйте два столбца, которые вам нужно отключить.

Затем, чтобы получить список столбцов сводным, изменить код, чтобы использовать как Author_number и затем строку с именами столбцов Family_Name и First_Name:

select @colsPivot = STUFF((SELECT ',' + QUOTENAME(c.col + '_'+cast(Author_Number as varchar(10))) 
        from Authors 
        cross apply 
        (
         select 'Family_Name' col, 1 so union all 
         select 'First_Name', 2 
        ) c 
        group by col, author_number, so 
        order by author_number, so 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

Это дает список перевалы:

|                      COLUMN_0 | 
------------------------------------------------------------------------------------------------ 
| [Family_Name_1],[First_Name_1],[Family_Name_2],[First_Name_2],[Family_Name_3],[First_Name_3] | 

Внесение этих изменений в код окончательный запрос будет

DECLARE @colsPivot AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @colsPivot = STUFF((SELECT ',' + QUOTENAME(c.col + '_'+cast(Author_Number as varchar(10))) 
        from Authors 
        cross apply 
        (
         select 'Family_Name' col, 1 so union all 
         select 'First_Name', 2 
        ) c 
        group by col, author_number, so 
        order by author_number, so 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 


set @query 
    = 'select Client_id, Project_id, Person_Id, '[email protected]+' 
     from 
     (
     select Client_id, Project_id, Person_Id, 
      col+''_''+cast(Author_Number as varchar(10)) col, val 
     from 
     (
      select Client_id, Project_id, 
      Person_Id, 
      Author_Number, 
      Family_Name, 
      First_Name 
      from Authors 
     ) s 
     unpivot 
     (
      val 
      for col in (Family_Name, First_Name) 
     ) u 
    ) x1 
     pivot 
     (
     max(val) 
     for col in ('+ @colspivot +') 
    ) p' 

exec(@query) 

См. SQL Fiddle with Demo. Это дает результат:

| CLIENT_ID | PROJECT_ID | PERSON_ID | FAMILY_NAME_1 | FIRST_NAME_1 | FAMILY_NAME_2 | FIRST_NAME_2 | FAMILY_NAME_3 | FIRST_NAME_3 | 
----------------------------------------------------------------------------------------------------------------------------------- 
|  TEST |  TEST |  12345 |   Giust |   Fede |   Ma |   Ke |  (null) |  (null) | 
|  TEST |  TEST |  12346 |   Jones |  Peter |  Davies |   Bob |  Richards |  Craig | 
+0

Выглядит очень перспективно! Большое спасибо за такой быстрый ответ! Я буду тестировать на нашем сервере и посмотреть, полезны ли полученные результаты. Я только вставил несколько столбцов в примере, но в исходной таблице около 30 столбцов. –

+0

Как я могу сделать это функцией или представлением? Это возможно? –

+0

@FedericoGiust Поскольку вы используете динамический SQL, он должен находиться в хранимой процедуре. Динамический SQL не разрешен в представлениях или функциях. – Taryn

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