sql >> Database >  >> RDS >> Sqlserver

PIVOT gebruiken in SQL Server 2005 Opgeslagen procedure die twee weergaven samenvoegt

U moet alle mogelijke waarden kennen om door te draaien. Het is dus moeilijk om dit rechtstreeks met T-SQL te doen, tenzij je dynamische SQL gebruikt en dit kan vrij snel harig worden. Waarschijnlijk is het beter om alle rijen terug te geven aan de presentatielaag of de schrijver van het rapport en deze opzij te laten draaien.

Hier is een snel PIVOT-voorbeeld als u alle UBCategory-waarden van tevoren kent. Ik heb ICCUDays weggelaten omdat het nogal irrelevant lijkt, tenzij er kolommen zijn die uit die weergave komen als onderdeel van het resultaat.

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;

Om dit dynamischer te maken, moet u de door komma's gescheiden lijst met DISTINCT UBCategory-waarden krijgen en de spil on-the-fly bouwen. Het kan er dus zo uitzien:

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;

Om vervolgens "de gegevens naar een nieuwe tabel te sturen", kunt u de query gewoon een INSERT INTO ... SELECT maken in plaats van een rechte SELECT. Dit lijkt natuurlijk een beetje nutteloos, want om die insert-instructie te schrijven, moet je de volgorde van de kolommen weten (wat niet gegarandeerd is met deze aanpak) en je moet al kolommen hebben ingevoerd voor elke potentiële UB-categorie waarde toch, dus dit lijkt erg kip en ei.




  1. zoeken vanuit meerdere tabellen met één trefwoord in mysql

  2. Batch verzenden van e-mail met SwiftMailer

  3. Tekens met accenten niet correct geïmporteerd met BULK INSERT

  4. EF en TransactionScope voor zowel SQL Server als Oracle zonder te escaleren/overspannen naar DTC?