Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Cách sử dụng PIVOT trong SQL Server 2005 Thủ tục được lưu trữ Kết hợp hai chế độ xem

Bạn cần biết tất cả các giá trị có thể để PIVOT bằng. Vì vậy, rất khó để thực hiện điều này trực tiếp với T-SQL trừ khi bạn sử dụng SQL động và điều này có thể trở nên khá nhanh chóng. Có lẽ tốt hơn nên chuyển tất cả các hàng trở lại tầng trình bày hoặc người viết báo cáo và để nó xoay chúng sang một bên.

Đây là một ví dụ PIVOT nhanh nếu bạn biết trước tất cả các giá trị của UBCategory. Tôi đã bỏ ICCUDays vì nó có vẻ không liên quan trừ khi có các cột xuất phát từ chế độ xem đó như một phần của kết quả.

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;

Để làm cho điều này năng động hơn, bạn phải nhận được danh sách các giá trị DISTINCT UBCategory được phân tách bằng dấu phẩy và tạo trục xoay một cách nhanh chóng. Vì vậy, nó có thể trông như thế này:

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;

Sau đó, để "gửi dữ liệu đến một bảng mới", bạn có thể chỉ cần đặt truy vấn là CHÈN VÀO ... CHỌN thay vì CHỌN thẳng. Tất nhiên, điều này có vẻ vô ích, bởi vì để viết câu lệnh chèn đó, bạn cần biết thứ tự của các cột (điều này không được đảm bảo với cách tiếp cận này) và bạn cần phải đặt sẵn các cột cho mỗi UBCategory tiềm năng dù sao cũng có giá trị, vì vậy điều này có vẻ rất giống gà và trứng.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Có cách nào để chỉ định tên bảng dưới dạng một chuỗi không?

  2. DT_Kiểu dữ liệu thập phân Cắt bỏ số thập phân

  3. Làm cách nào tôi có thể xác thực trong SQL SERVER 2008 với Người dùng Active Directory nhưng không có Xác thực Windows

  4. SQL Server 2005 - sử dụng chuỗi được tạo thay vì cột Identity?

  5. Tạo chế độ xem trên nhiều cơ sở dữ liệu