PIVOT
テーブルの要素(COLUMN LIKE='Value%'
など)でグループ化することはできますか? (データベース、インスタンスなどの)さまざまなステータスを含むテーブル[DBT]。[Status]があり、すべてのPRODとTESTの値を単一の値としてピボット/クエリしたくありませんが、それらをグループ化します。
例えば。ステータスProd
、Prod ACC
、Prod APP
などの列を作成する代わりに、Name LIKE 'Prod%'
とName LIKE 'Test%'
の値を含む列は1つだけです。
これまでのところ:
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
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
名前の数が限られている場合、次のように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 <> fiddle ここ
動的クエリ
少し面倒だと感じて、すべての列名を書きたくない場合は、動的クエリを使用できます。
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 <> fiddle ここ
ここで1つのステップで実行しようとしている2つのタスクを厳密に分離することが重要だと思います。
データを分類するために、ここでの私の本能は、レコードを親クラスに厳密にマップするためのルックアップテーブルを推奨することです。例えば.
CREATE TABLE StatusType (
ID INT IDENTITY PRIMARY KEY,
[Name] VARCHAR(10) NOT NULL UNIQUE
);
GO
ALTER TABLE [Status]
ADD StatusTypeID INT NOT NULL
DEFAULT 1
FOREIGN KEY REFERENCES StatusType (ID) ;
...ここで、シードレコードはStatusType
(ID
= 1のStatus.StatusTypeID
default)は、「不明」などの名前のプレースホルダーレコードです。
ルックアップデータがシードされ、ベースレコードが正しいキーで更新されると、心のコンテンツにピボットできます。
select 'Database Status' AS [DB Status],
[Test], [Prod], [Migrated], [Offline], [Reserved]
from (
select s.ID,
st.Name as StatusTypeName
from status s
join statusType st on st.ID = s.StatusTypeID
) as Source
pivot (
count(ID) for StatusTypeName in ([Test],[Prod],[Migrated],[Offline],[Reserved],[Unknown])
) as pvt;