2013-11-27 5 views
0

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

Tname FY FPY Week 
test1 87 78 1 
test1 45 34 2 
test1 34 89 3 
test1 34 56 4 
test1 56 78 5 
test1 68 45 6 
test2 45 89 1 
test2 76 65 2 
test2 45 54 3 
test3 56 57.8 2 
test4 34 55 4 
test4 32 52.2 7 
test3 78 49.4 3 
test5 89 46.6 2 
test5 90 43.8 1 
test5 98 41 6 
test5 91 38.2 7 
test6 92 35.4 5 
test6 93 32.6 6 

для отображения результатов AS

Tname week1  Week2  Week3  Week4  Week5  Week6  Week7 
    FY FPY FY FPY FY FPY FY FPY FY FPY FY FPY FY FPY 
test1 87 78 45 34 34 89 34 56 56 78 68 45 NULL NULL 
test2 45 89 76 65 45 54 NULL NULL NULL NULL NULL NULL NULL NULL 
test3 NULL NULL 56 57.8 78 49.4 NULL NULL NULL NULL NULL NULL NULL NULL 
test4 NULL NULL NULL NULL NULL NULL 34 55 NULL NULL NULL NULL 32 52.2 
test5 90 43.8 89 46.6 NULL NULL NULL NULL NULL NULL 98 41 91 38.2 
test6 NULL NULL NULL NULL NULL NULL NULL NULL 92 35.4 93 32.6 NULL NULL 

Я хотел бы добиться этого с помощью хранимой процедуры или GridView , Пожалуйста, сообщите

+0

По крайней мере, вы можете понять свой пост? – user2989408

+0

Попробуйте использовать [PIVOT] (http://technet.microsoft.com/en-us/library/ms177410%28v=sql.105%29.aspx) для преобразования данных строки в данные столбца. – user2989408

+2

Пожалуйста, укажите СУБД, на которые вы нацеливаете, добавив соответствующий тег (Oracle, SQL Server, MySQL и т. Д.). Могут быть ответы, которые используют преимущества языка или функций продукта, которые не поддерживаются повсеместно. Кроме того, пометив его конкретными СУБД, ваш вопрос может привлечь внимание от людей, более подходящих для ответа на него. – Taryn

ответ

1

Вы не указали, какие СУБД вы используете, но ваши предыдущие вопросы были отмечены SQL Server, поэтому этот ответ предполагает, что в качестве вашей базы данных.

Есть несколько способов получить результат. Один простой способ, будет использовать агрегатную функцию с выражением CASE, аналогично:

select tname, 
    sum(case when week = 1 then FY end) Week1FY, 
    sum(case when week = 1 then FPY end) Week1FPY, 
    sum(case when week = 2 then FY end) Week2FY, 
    sum(case when week = 2 then FPY end) Week2FPY, 
    sum(case when week = 3 then FY end) Week3FY, 
    sum(case when week = 3 then FPY end) Week3FPY, 
    sum(case when week = 4 then FY end) Week4FY, 
    sum(case when week = 4 then FPY end) Week4FPY, 
    sum(case when week = 5 then FY end) Week5FY, 
    sum(case when week = 5 then FPY end) Week5FPY, 
    sum(case when week = 6 then FY end) Week6FY, 
    sum(case when week = 6 then FPY end) Week6FPY, 
    sum(case when week = 7 then FY end) Week7FY, 
    sum(case when week = 7 then FPY end) Week7FPY 
from yourtable 
group by tname; 

SQL Fiddle with Demo См.

Поскольку вам нужно PIVOT на двух столбцах, сначала вы должны отключить данные в столбцах FY и FPY, а затем применить функцию PIVOT. Опять же в зависимости от РСУБД, есть несколько способов UNPIVOT данные я показываю, как сделать это с помощью CROSS ОТНОСИТЬСЯ и UNION ALL:

select tname, 
    col = 'week_'+cast(week as varchar(2))+'_'+col, 
    value 
from yourtable 
cross apply 
(
    select 'FY', FY union all 
    select 'FPY', FPY 
) c (col, value) 

UNPIVOT процесс преобразует данные из нескольких столбцов на несколько строк:

| TNAME |  COL | VALUE | 
|-------|------------|-------| 
| test1 | week_1_FY | 87 | 
| test1 | week_1_FPY | 78 | 
| test1 | week_2_FY | 45 | 
| test1 | week_2_FPY | 34 | 
| test1 | week_3_FY | 34 | 

Затем вы можете применить функцию PIVOT:

select tname, 
    week_1_FY, week_1_FPY, week_2_FY, week_2_FPY, 
    week_3_FY, week_3_FPY, week_4_FY, week_4_FPY, 
    week_5_FY, week_5_FPY, week_6_FY, week_6_FPY, 
    week_7_FY, week_7_FPY 
from 
(
    select tname, 
    col = 'week_'+cast(week as varchar(2))+'_'+col, 
    value 
    from yourtable 
    cross apply 
    (
    select 'FY', FY union all 
    select 'FPY', FPY 
) c (col, value) 
) d 
pivot 
(
    sum(value) 
    for col in (week_1_FY, week_1_FPY, week_2_FY, week_2_FPY, 
       week_3_FY, week_3_FPY, week_4_FY, week_4_FPY, 
       week_5_FY, week_5_FPY, week_6_FY, week_6_FPY, 
       week_7_FY, week_7_FPY) 
) piv; 

См SQL Fiddle with Demo.

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

DECLARE @cols AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX), 
    @weekstart int = 1, 
    @weekend int = 4 

select @cols = STUFF((SELECT ',' + QUOTENAME('week_'+cast(week as varchar(2))+'_'+col) 
        from yourtable 
        cross apply 
        (
         select 'FY', 1 union all 
         select 'FPY', 2 
        ) c (col, so) 
        where week >= @weekstart 
         and week <= @weekend 
        group by col, so, week 
        order by week, so 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT tname, ' + @cols + ' 
      from 
      (
       select tname, 
       col = ''week_''+cast(week as varchar(2))+''_''+col, 
       value 
       from yourtable 
       cross apply 
       (
       select ''FY'', FY union all 
       select ''FPY'', FPY 
      ) c (col, value) 
       where week >= '+cast(@weekstart as varchar(2))+' 
       and week <= '+cast(@weekend as varchar(2))+' 
      ) x 
      pivot 
      (
       sum(value) 
       for col in (' + @cols + ') 
      ) p ' 

execute sp_executesql @query; 

См SQL Fiddle with Demo. Все версии дают результат:

| TNAME | WEEK_1_FY | WEEK_1_FPY | WEEK_2_FY | WEEK_2_FPY | WEEK_3_FY | WEEK_3_FPY | WEEK_4_FY | WEEK_4_FPY | WEEK_5_FY | WEEK_5_FPY | WEEK_6_FY | WEEK_6_FPY | WEEK_7_FY | WEEK_7_FPY | 
|-------|-----------|------------|-----------|------------|-----------|------------|-----------|------------|-----------|------------|-----------|------------|-----------|------------| 
| test1 |  87 |   78 |  45 |   34 |  34 |   89 |  34 |   56 |  56 |   78 |  68 |   45 | (null) |  (null) | 
| test2 |  45 |   89 |  76 |   65 |  45 |   54 | (null) |  (null) | (null) |  (null) | (null) |  (null) | (null) |  (null) | 
| test3 | (null) |  (null) |  56 |   58 |  78 |   49 | (null) |  (null) | (null) |  (null) | (null) |  (null) | (null) |  (null) | 
| test4 | (null) |  (null) | (null) |  (null) | (null) |  (null) |  34 |   55 | (null) |  (null) | (null) |  (null) |  32 |   52 | 
| test5 |  90 |   44 |  89 |   47 | (null) |  (null) | (null) |  (null) | (null) |  (null) |  98 |   41 |  91 |   38 | 
| test6 | (null) |  (null) | (null) |  (null) | (null) |  (null) | (null) |  (null) |  92 |   35 |  93 |   33 | (null) |  (null) | 
+0

Большое спасибо! Это очень помогло мне. Я добираюсь до этого формата данных (как задано в вопросе) с использованием очень сложной хранимой процедуры и многих соединений со многими таблицами. Итак, мой вопрос: возможно ли, чтобы colnames были динамическими. Иногда это может быть неделя номер 10-15 и некоторые другие времена 10-20 или 15-17 и т. Д. Это могут быть любые номера в неделю. Любые указатели были бы полезны. – user1984533

+0

@ user1984533 Да, вы можете использовать динамический sql, если недели неизвестны, см. Мое редактирование – Taryn

+0

Спасибо Bluefeet! Действительно ценю это!!!!! – user1984533

0

попробовать что-то вроде

SELECT * 
FROM (
    SELECT TName, [1] as Week1FY, [2] as Week2FY, [3] as Week3FY, 
     [4] as Week4FY, [5] as Week5FY, [6] as Week6FY, [7] as Week7FY 
    FROM(SELECT t.TName, t.FY, t.Week FROM Table t 
    PIVOT 
     (MAX(FY) FOR Week in ([1], [2], [3], [4], [5], [6], [7]) 
    )) as P 
    JOIN 
    (
    SELECT TName, [1] as Week1FPY, [2] as Week2FPY, [3] as Week3FPY, 
     [4] as Week4FPY, [5] as Week5FPY, [6] as Week6FPY, [7] as Week7FPY 
    FROM(SELECT t.TName, t.FPY, t.Week FROM Table t 
    PIVOT 
     (MAX(FPY) FOR Week in ([1], [2], [3], [4], [5], [6], [7]) 
    )) as Q ON P.TName = Q.TName 
+0

Спасибо за ваш ответ! Внимательно оцените время, которое вы приняли, чтобы ответить. – user1984533

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