Sql-Server

是否可以在 LIKE 語句上進行 PIVOT

  • February 15, 2022

是否可以按表格中的元素(如COLUMN LIKE='Value%')分組PIVOT?我有一張桌子

$$ DBT $$.$$ Status $$它包含各種狀態(數據庫、實例等),並且不想將所有 PROD 和 TEST 值作為單個值進行透視/查詢,而是將它們分組。 例如,我將只有一列包含 和 的值,而不是列用於狀態ProdProd 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<>在這裡擺弄

引用自:https://dba.stackexchange.com/questions/247411