sql >> Databasteknik >  >> RDS >> Sqlserver

Hur man använder PIVOT i SQL Server 2005 lagrad procedur som går samman med två vyer

Du måste känna till alla möjliga värden att PIVOT efter. Så det är svårt att göra detta med T-SQL direkt om du inte använder dynamisk SQL och detta kan bli hårigt ganska snabbt. Det är förmodligen bättre att skicka tillbaka alla rader till presentationsnivån eller rapportskrivaren och låta den vända dem åt sidan.

Här är ett snabbt PIVOT-exempel om du känner till alla UBCategory-värden i förväg. Jag utelämnade ICCUDays eftersom det verkar ganska irrelevant om det inte finns kolumner som kommer från den uppfattningen som en del av resultatet.

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;

För att göra detta mer dynamiskt måste du skaffa den kommaseparerade listan med DISTINKT UBCategory-värden och bygga pivoten i farten. Så det kan se ut så här:

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;

För att sedan "skicka data till en ny tabell" kan du bara göra frågan till en INSERT INTO ... SELECT istället för en rak SELECT. Naturligtvis verkar det här vara meningslöst, för för att kunna skriva den infogningssatsen måste du känna till kolumnernas ordning (vilket inte garanteras med detta tillvägagångssätt) och du måste redan ha lagt in kolumner för varje potentiell UBC-kategori värde ändå, så det här verkar väldigt kyckling och ägg.




  1. Hur man använder google translate URL i Oracle plsql

  2. Trigger i SQL

  3. NCHAR(1) vs BIT

  4. Använda en markör i en lagrad procedur för att loopa rader MySQL