sql >> Database teknologi >  >> RDS >> Sqlserver

Sådan bruges PIVOT i SQL Server 2005 Stored Procedure, der forbinder to visninger

Du skal kende alle de mulige værdier at PIVOT efter. Så det er svært at gøre dette med T-SQL direkte, medmindre du bruger dynamisk SQL, og dette kan ret hurtigt blive behåret. Det er nok bedre at sende alle rækkerne tilbage til præsentationsniveauet eller rapportskriveren og lade dem vende dem til siden.

Her er et hurtigt PIVOT-eksempel, hvis du kender alle UBCategory-værdierne på forhånd. Jeg har udeladt ICCUDays, da det virker ret irrelevant, medmindre der er kolonner, der kommer fra det synspunkt som en del af 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;

For at gøre dette mere dynamisk, skal du hente den kommaseparerede liste over DISTINCT UBCategory-værdier og bygge pivoten på farten. Så det kan se sådan ud:

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;

Så for at "sende dataene til en ny tabel" kan du bare gøre forespørgslen til en INSERT INTO ... SELECT i stedet for en straight SELECT. Det virker selvfølgelig lidt ubrugeligt, for for at kunne skrive den indsættelseserklæring skal du kende rækkefølgen af ​​kolonnerne (hvilket ikke er garanteret med denne tilgang), og du skal allerede have indsat kolonner for hver potentiel UBC-kategori værdi alligevel, så det virker meget kylling og æg.




  1. Hent mysql-tabelkommentar ved hjælp af DatabaseMetaData

  2. MySql får optegnelser eller data dagligt, ugentligt, månedligt og årligt

  3. Bestemmelse af, om feltdataene i Oracle er af nummertypen

  4. Sådan fungerer LOG() i MariaDB