Sql-Server
是否可以在 LIKE 語句上進行 PIVOT
是否可以按表格中的元素(如
COLUMN LIKE='Value%'
)分組PIVOT
?我有一張桌子$$ DBT $$.$$ Status $$它包含各種狀態(數據庫、實例等),並且不想將所有 PROD 和 TEST 值作為單個值進行透視/查詢,而是將它們分組。 例如,我將只有一列包含 和 的值,而不是列用於狀態
Prod
、Prod ACC
、 、 ..等。Prod APP``Name LIKE 'Prod%'``Name LIKE 'Test%'
到目前為止我所擁有的:
表定義
CREATE TABLE [DBT].[Status]( [ID] [int] IDENTITY(1,1) NOT NULL, [Name] [nvarchar](50) NOT NULL, CONSTRAINT [PK_Status] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY], CONSTRAINT [IX_Status] UNIQUE NONCLUSTERED ( [Name] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY] ) ON [PRIMARY] GO
表值
INSERT INTO [DBT].[Status] ( -- ID -- this column value is auto-generated Name ) VALUES ('Test ACC'), ('Test APP'), ('Test DBA'), ('Prod ACC'), ('Prod APP'), ('Prod DBA'), ('Prod'), ('Test'), ('Migrated'), ('Offline'), ('Reserved')
透視狀態表
SELECT 'Database Status' AS [DB Status], [1] AS [Test ACC], [2] AS [Test APP], [3] AS [Test DBA], [4] AS [Prod ACC], [5] AS [Prod APP], [6] AS [Prod DBA], [7] AS [Prod], [8] AS [Test], [9] AS [Migrated], [10] AS [Offline], [11] AS [Reserved] FROM ( SELECT ID, Name FROM [DBT].[Status] ) AS Source PIVOT ( COUNT(Name) FOR ID IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11]) ) AS PivotTable
到目前為止的輸出
DB Status Test ACC Test APP Test DBA Prod ACC Prod APP Prod DBA Prod Test Migrated Offline Reserved --------------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- Database Status 1 1 1 1 1 1 1 1 1 1 1
db<>小提琴
到目前為止的dbfiddle 。
問題
我寧願將它們分組,而不是為各種
Test...
和值設置多行,類似於以下內容:Prod....
DB Status | Test | Prod | Migrated | Offline | Reserved --------------- | ---- | ---- | -------- | ------- | -------- Database Status | 4 | 4 | 1 | 1 | 1
我不知道如何解決我的問題。(老實說,經過大量的反複試驗,我昨天才掌握了 PIVOT)。
這個問題與我已經問過的*如何在多個表上創建分組項目的總和/計數*問題鬆散相關。桌子$$ DBT $$.$$ Instance $$和$$ DBT $$.$$ Database $$包含一列$$ StatusID $$這對應於我們現在正在查看的表格。
總和(案例
對於有限數量的名稱,您可以通過這種方式使用 SUM(CASE 解決方案:
SELECT 'Database status' as [DB Status], SUM(CASE WHEN Name LIKE 'Test%' THEN 1 ELSE 0 END) As Test, SUM(CASE WHEN Name LIKE 'Prod%' THEN 1 ELSE 0 END) AS Prod, SUM(CASE WHEN Name = 'Migrated' THEN 1 ELSE 0 END) AS Migrated, SUM(CASE WHEN Name = 'Offline' THEN 1 ELSE 0 END) AS Offline, SUM(CASE WHEN Name = 'Reserved' THEN 1 ELSE 0 END) AS Reserved FROM [Status];
樞
如果有一個廣泛的名稱列表,但只有少數必須重寫,您可以維護 PIVOT 解決方案:
SELECT 'Database Status' AS [DB Status], [Test], [Prod], [Migrated], [Offline], [Reserved] FROM ( SELECT ID, CASE WHEN Name LIKE 'Test%' THEN 'Test' WHEN Name LIKE 'Prod%' THEN 'Prod' ELSE Name END AS Name FROM [Status] ) AS Source PIVOT ( COUNT(ID) FOR Name IN ([Test], [Prod], [Migrated], [Offline], [Reserved]) ) AS PivotTable;
db<>在這裡擺弄
動態查詢
如果你覺得有點懶,不想寫所有列名,可以使用動態查詢:
DECLARE @cols nvarchar(max); SET @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(CASE WHEN Name LIKE 'Test%' THEN 'Test' WHEN Name LIKE 'Prod%' THEN 'Prod' ELSE Name END) FROM [Status] FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, ''); DECLARE @cmd nvarchar(max); SET @cmd = 'SELECT ''Database Status'' AS [DB Status],' + @cols + ' FROM (SELECT ID, CASE WHEN Name LIKE ''Test%'' THEN ''Test'' WHEN Name LIKE ''Prod%'' THEN ''Prod'' ELSE Name END AS Name FROM [Status] ) AS Source PIVOT ( COUNT(ID) FOR Name IN (' + @cols + ') ) PVT' EXEC(@cmd);
db<>在這裡擺弄