sql >> Databáze >  >> RDS >> Sqlserver

Jak používat PIVOT v SQL Server 2005 Stored Procedure Joining Two Views

Musíte znát všechny možné hodnoty, podle kterých PIVOT. Je tedy obtížné to udělat přímo s T-SQL, pokud nepoužíváte dynamické SQL, a to se může rychle zvrhnout. Pravděpodobně bude lepší předat všechny řádky zpět do vrstvy prezentace nebo zapisovače sestav a nechat je otočit na stranu.

Zde je rychlý příklad PIVOT, pokud znáte všechny hodnoty UBCategory předem. ICCUDays jsem vynechal, protože se zdá být spíše irelevantní, pokud nejsou sloupce, které pocházejí z tohoto pohledu jako součást výsledku.

USE tempdb;
GO
SET NOCOUNT ON;
GO

-- who on earth is responsible for your naming scheme?
CREATE TABLE dbo.ICCUEnctrSelectedRevCatsDirCost
(
    Account INT,
    UBCategory VARCHAR(10),
    DirectCost DECIMAL(9,2)
);

INSERT dbo.ICCUEnctrSelectedRevCatsDirCost
    SELECT 1, 'foo', 5.25
    UNION SELECT 1, 'bar', 6.25
    UNION SELECT 1, 'smudge', 8.50
    UNION SELECT 2, 'foo', 9.25
    UNION SELECT 2, 'brap', 2.75;

SELECT Account,[foo],[bar],[smudge],[brap] FROM 
    dbo.ICCUEnctrSelectedRevCatsDirCost
    -- WHERE <something>, I assume ???
PIVOT
(
    MAX(DirectCost)
    FOR UBCategory IN ([foo],[bar],[smudge],[brap])
) AS p;

GO
DROP TABLE dbo.ICCUEnctrSelectedRevCatsDirCost;

Aby to bylo dynamičtější, museli byste získat čárkami oddělený seznam hodnot DISTINCT UBCategory a vytvořit pivot za běhu. Může to tedy vypadat takto:

USE tempdb;
GO
SET NOCOUNT ON;
GO

-- who on earth is responsible for your naming scheme?
CREATE TABLE dbo.ICCUEnctrSelectedRevCatsDirCost
(
    Account INT,
    UBCategory VARCHAR(10),
    DirectCost DECIMAL(9,2)
);

INSERT dbo.ICCUEnctrSelectedRevCatsDirCost
    SELECT 1, 'foo', 5.25
    UNION SELECT 1, 'bar', 6.25
    UNION SELECT 1, 'smudge', 8.50
    UNION SELECT 2, 'foo', 9.25
    UNION SELECT 2, 'brap', 2.75
    UNION SELECT 3, 'bingo', 4.00;

DECLARE @sql NVARCHAR(MAX),
    @col NVARCHAR(MAX);

SELECT @col = COALESCE(@col, '') + QUOTENAME(UBCategory) + ','
    FROM 
    (
        SELECT DISTINCT UBCategory
        FROM dbo.ICCUEnctrSelectedRevCatsDirCost
    ) AS x;

SET @col = LEFT(@col, LEN(@col)-1);

SET @sql = N'SELECT Account, $col$ FROM 
    dbo.ICCUEnctrSelectedRevCatsDirCost
    -- WHERE <something>, I assume ???
PIVOT
(
    MAX(DirectCost)
    FOR UBCategory IN ($col$)
) AS p;';

SET @sql = REPLACE(@sql, '$col$', @col);

--EXEC sp_executeSQL @sql;
PRINT @sql;

GO
DROP TABLE dbo.ICCUEnctrSelectedRevCatsDirCost;

Chcete-li pak „odeslat data do nové tabulky“, stačí zadat dotaz INSERT INTO ... SELECT namísto přímého SELECT. Samozřejmě se to zdá být trochu zbytečné, protože abyste mohli napsat ten příkaz insert, musíte znát pořadí sloupců (což není u tohoto přístupu zaručeno) a musíte mít již vložené sloupce pro každou potenciální kategorii UBC hodnotu tak jako tak, takže to vypadá velmi slepice a vejce.




  1. MySQL:Souběžné aktualizace (prostřednictvím vláken) na jednoduché tabulce

  2. Jaké je největší ID číslo, které může autoinkrement vytvořit v mysql

  3. Sloučit hodnoty řádků do CSV (neboli GROUP_CONCAT pro SQL Server)

  4. php nahradit klíče ID pole