2012-03-06 2 views
4

У меня есть таблица (элементы), который находится в следующем формате:SQL Server Повороты: Отображение значений строк с заголовками столбцов

ITEMNO | WEEKNO | VALUE 
A1234 | 1 | 805 
A2345 | 2 | 14.50 
A3547 | 2 | 1396.70 
A2208 | 1 | 17.65 
A4326 | 6 | 19.99 

это таблица, которая показывает значение продаж для элементов в данной неделе.

Результаты или то, что я хочу отобразить в формате таблицы, - это номер позиции в строке, за которым следуют столбцы на каждую неделю, содержащие значения, например.

ITEMNO | WK1 | WK2 | WK3 | WK4 | WK5 ...etc up to 52 
A1234 | 805 | 345 | 234 | 12 | 10 ...etc up to 52 
A2345 | 23 | 12 | 456 | 34 | 99 ...etc up to 52 
A3456 | 234 | 123 | 34 | 25 | 190 ...etc up to 52 

Хотя у меня 52 ... поэтому у меня есть только данные до недели9, но со временем это будет увеличиваться.

Так что в основном то, что я ищу для отображения, является значением номера недели в качестве заголовка столбца.

Возможно ли это, хотя я соблазн просто захватить данные и правильно отобразить их с помощью кода/(asp.net), но мне было интересно, не было ли там отображать его так, как в SQL?

Кто-нибудь знает или думает, что это может быть лучший способ?

+1

Пожалуйста, проголосуйте для динамического поворота для следующей версии SQL Server (не SQL 2012)! http://connect.microsoft.com/SQLServer/feedback/details/127071/pivot –

+0

.......... done :) – thegunner

ответ

6

Есть два способа сделать это с помощью статического SQL и динамического SQL:

Static Pivot :

SELECT P.ItemNo, IsNull(P.[1], 0) as Wk1, IsNull(P.[2], 0) as Wk2 
    , IsNull(P.[3], 0) as Wk3, IsNull(P.[4], 0) as Wk4 
    , IsNull(P.[5], 0) as Wk5, IsNull(P.[6], 0) as Wk6 
    , IsNull(P.[7], 0) as Wk7, IsNull(P.[8], 0) as Wk8 
    , IsNull(P.[9], 0) as Wk9 
FROM 
(
    SELECT ItemNo, WeekNo, [Value] 
    FROM dbo.Items 
) I 
PIVOT 
(
    SUM([Value]) 
    FOR WeekNo IN ([1], [2], [3], [4], [5], [6], [7], [8], [9]) 
) as P 

Dynamic Pivot:

DECLARE 
@cols AS NVARCHAR(MAX), 
@y AS INT, 
@sql AS NVARCHAR(MAX); 

-- Construct the column list for the IN clause 
SET @cols = STUFF(
(SELECT N',' + QUOTENAME(w) AS [text()] 
FROM (SELECT DISTINCT WeekNo AS W FROM dbo.Items) AS W 
ORDER BY W 
FOR XML PATH('')), 
1, 1, N''); 


-- Construct the full T-SQL statement 
-- and execute dynamically 
SET @sql = N'SELECT * 
      FROM (SELECT ItemNo, WeekNo, Value 
        FROM dbo.Items) AS I 
      PIVOT(SUM(Value) FOR WeekNo IN(' + @cols + N')) AS P;'; 

EXEC sp_executesql @sql; 
GO 
+0

Пользуясь вашим Dymanic ответом ... фантастическим;) – thegunner

+0

@bluefeet Is есть ли польза для использования «NVARCHAR» и «VARCHAR»? – Kermit

+0

@njk см. [Этот ответ] (http://stackoverflow.com/questions/144283/what-is-the-difference-between-varchar-and-nvarchar) – Taryn

1

Использование Pivot, хотя совсем немного кода .. При создании отчета в службах отчетов, можно использовать матрицу ..

1

Вы можете использовать PIVOT, если вы хотите сделать это непосредственно в sql.

Это может быть более эффективно использовать SQL Server для этого, в отличие от клиента, в зависимости от размера данных и агрегации.

3

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

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

CREATE TABLE #tbl 
    (
     ITEMNO VARCHAR(100), 
     WEEKNO INT, 
     VALUE FLOAT 
    ) 

INSERT INTO #tbl 
VALUES 
    ('A1234',1,805), 
    ('A2345',2,14.50), 
    ('A3547',2,1396.70), 
    ('A2208',1,17.65), 
    ('A4326',6,19.99) 

неделя колонны

DECLARE @cols VARCHAR(MAX) 

;WITH Nbrs (n) AS (
     SELECT 1 UNION ALL 
     SELECT 1 + n FROM Nbrs WHERE n < 52) 
SELECT @cols = COALESCE(@cols + ','+QUOTENAME('WK'+CAST(n AS VARCHAR(2))), 
        QUOTENAME('WK'+CAST(n AS VARCHAR(2)))) 
FROM 
    Nbrs 

Просто включенные недели

DECLARE @cols VARCHAR(MAX) 
;WITH CTE 
AS 
(
    SELECT 
     ROW_NUMBER() OVER(PARTITION BY WEEKNO ORDER BY WEEKNO) AS RowNbr, 
     WEEKNO 
    FROM 
     #tbl 
) 
SELECT @cols = COALESCE(@cols + ','+QUOTENAME('WK'+CAST(WEEKNO AS VARCHAR(2))), 
        QUOTENAME('WK'+CAST(WEEKNO AS VARCHAR(2)))) 
FROM 
    CTE 
WHERE 
    CTE.RowNbr=1 

Динамический поворотный

DECLARE @query NVARCHAR(4000)= 
N'SELECT 
    * 
FROM 
(
    SELECT 
     tbl.ITEMNO, 
     ''WK''+CAST(tbl.WEEKNO AS VARCHAR(2)) AS WEEKNO, 
     tbl.VALUE 
    FROM 
     #tbl as tbl 
) AS p 
PIVOT 
(
    SUM(VALUE) 
    FOR WEEKNO IN ('[email protected]+') 
) AS pvt' 
EXECUTE(@query) 

Капля таблица температуры

DROP TABLE #tbl 
Смежные вопросы