2012-04-03 5 views
3

У меня есть таблица вроде этого:SQL Server 2008 - Создание таблицы динамически из другой таблицы

Column = NAME 
Column = DATE 

NAME | DATE  | Y/N 
John | 01/01/2012 | bit 
Mary | 01/01/2012 | bit 
James | 01/01/2012 | bit 
John | 01/02/2012 | bit 
Mary | 01/02/2012 | bit 
James | 01/02/2012 | bit 
John | 01/03/2012 | bit 
Mary | 01/03/2012 | bit 
James | 01/03/2012 | bit 

Я хочу создать некоторую форму матрицы или поворота, так что я в конечном итоге с этим:

NAME | 01/01/2012 | 01/02/2012 | 01/03/2012 
John | bit  | bit  | bit 
Mary | bit  | bit  | bit 
James | bit  | bit  | bit 

Я видел несколько примеров поворота, которые содержат небольшое количество элементов столбца (например, Banana, Apple, Orange). Мне нужно иметь неопределенное количество имен и неопределенное количество дат (так, без жестко заданных имен столбцов). Я думал о разделении на несколько таблиц, но мне всегда нужно динамически создавать столбцы даты или столбцы имен.

Может ли кто-нибудь помочь?

+0

Спасибо вам Bluefeet для убираю, я нуб здесь так не может публиковать изображения: D – AlwaysLearning

ответ

5

Может быть что-то вроде этого:

Тестовые данные

CREATE TABLE Table1 
(
    NAME VARCHAR(100), 
    [DATE] DATE, 
    [Y/N] BIT 
) 

INSERT INTO Table1 
VALUES 
    ('John','01/01/2012',1), 
    ('Mary','01/01/2012',0), 
    ('James','01/01/2012',1), 
    ('John','01/02/2012',0), 
    ('Mary','01/02/2012',1), 
    ('James','01/02/2012',1), 
    ('John','01/03/2012',1), 
    ('Mary','01/03/2012',0), 
    ('James','01/03/2012',0) 

В поисках уникальных столбцов

DECLARE @cols VARCHAR(MAX) 
;WITH CTE 
AS 
(
    SELECT 
     ROW_NUMBER() OVER(PARTITION BY [DATE] ORDER BY [DATE]) AS RowNbr, 
     convert(varchar, [DATE], 103) AS [Date] 
    FROM 
     Table1 
) 
SELECT @cols=STUFF 
(
    (
     SELECT 
      ',' +QUOTENAME([Date]) 
     FROM 
      CTE 
     WHERE 
      CTE.RowNbr=1 
    FOR XML PATH('') 
    ) 
,1,1,'') 

Declare и выполнения динамического SQL

DECLARE @query NVARCHAR(4000)= 
N'SELECT 
    * 
FROM 
(
    SELECT 
     Table1.NAME, 
     CAST(Table1.[Y/N] AS INT) AS [Y/N], 
     convert(varchar, Table1.[DATE], 103) AS [Date] 
    FROM 
     Table1 
) AS p 
PIVOT 
(
    MAX([Y/N]) 
    FOR [Date] IN ('[email protected]+') 
) AS pvt' 

EXECUTE(@query) 

Очистка после себя

DROP TABLE Table1 

Результат

Name  01/01/2012 02/01/2012  03/01/2012 
James  1    1    0 
John  1    0    1 
Mary  0    1    0 
+0

Спасибо всем за вашу помощь, я искренне благодарю вас за то, что вы тратите время и силы, чтобы кратко решить мою проблему. У меня отличный день, как я буду – AlwaysLearning

1

Если у вас есть только несколько столбцов вы можете использовать статический стержень:

create table #temp 
(
    name varchar(50), 
    date datetime, 
    yesno bit 
) 

insert into #temp values('John', '01/01/2012', 1) 
insert into #temp values('Mary', '01/01/2012', 1) 
insert into #temp values('James', '01/01/2012', 1) 
insert into #temp values('John', '01/02/2012', 0) 
insert into #temp values('Mary', '01/02/2012', 0) 
insert into #temp values('James', '01/02/2012', 0) 
insert into #temp values('John', '01/03/2012', 1) 
insert into #temp values('Mary', '01/03/2012', 0) 
insert into #temp values('James', '01/03/2012', 1) 

select name, [01/01/2012], [01/02/2012], [01/03/2012] 
from 
(
    select name, date, cast(yesno as tinyint) as yesno 
    from #temp 
) x 
pivot 
(
    max(yesno) 
    for date in ([01/01/2012], [01/02/2012], [01/03/2012]) 
) p 

drop table #temp 

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

create table test 
(
    name varchar(50), 
    date datetime, 
    yesno bit 
) 

insert into test values('John', '01/01/2012', 1) 
insert into test values('Mary', '01/01/2012', 1) 
insert into test values('James', '01/01/2012', 1) 
insert into test values('John', '01/02/2012', 0) 
insert into test values('Mary', '01/02/2012', 0) 
insert into test values('James', '01/02/2012', 0) 
insert into test values('John', '01/03/2012', 1) 
insert into test values('Mary', '01/03/2012', 0) 
insert into test values('James', '01/03/2012', 1) 

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

SELECT @cols = STUFF((SELECT DISTINCT TOP 100 PERCENT 
           '],[' + convert(varchar(10), t2.date, 101) 
         FROM test AS t2 
         ORDER BY '],[' + convert(varchar(10), t2.date, 101) 
         FOR XML PATH('') 
        ), 1, 2, '') + ']' 


set @query = 'select name, ' + @cols + ' 
      from 
      (
       select name, date, cast(yesno as tinyint) as yesno 
       from test 
      ) x 
      pivot 
      (
       max(yesno) 
       for date in (' + @cols + ') 
      ) p' 


execute(@query) 

Вот некоторые полезные ссылки на динамические шарниров:

Pivots with Dynamic Columns in SQL Server

Using SQL Server 2005/2008 Pivot on Unknown Number of Columns (Dynamic Pivot)

там много вопросов/ответов на SO для динамических опор.

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