Is it possible to PIVOT on a LIKE statementHow to create sums/counts of grouped items over multiple tablesParent-Child Tree Hierarchical ORDERdeteriorating stored procedure running timesHow to use PIVOT here?How to create sums/counts of grouped items over multiple tablesSQL Server 2016 concurrency limitations? Tuning for db concurrencyNeed help in PivotTips on reshaping data, pivot-like?Dynamic dates PivotPivot data type error
Sol Ⅲ = Earth: What is the origin of this planetary naming scheme?
My favorite color is blue what is your favorite color?
Random point on a sphere
Do any aircraft carry boats?
The Royal Mint of Alphagonia
Why does F + F' = 1?
My research paper filed as a patent in China by my Chinese supervisor without me as inventor
Dividing Divisive Divisors
Can I say "I have encrypted something" if I hash something?
What is the use of FullForm in Mathematica?
Should I use my toaster oven for slow roasting?
Writing a worded mathematical expression
Did Picard get in trouble when he was in command of the Stargazer and lost his ship?
Relevance of the Resurrection
Variable Prefixes and Suffixes
How to easily add discontinuity on x-axis?
Has any object launched from Earth gone into the Sun?
Is there a star over my head?
Are Democrats more likely to believe Astrology is a science?
How can a resurrection system prevent the cheapening of death?
Why do sellers care about down payments?
Is the space of Radon measures a Polish space or at least separable?
Is BitLocker useful in the case of stolen laptop?
Why are some Mac apps not available on AppStore?
Is it possible to PIVOT on a LIKE statement
How to create sums/counts of grouped items over multiple tablesParent-Child Tree Hierarchical ORDERdeteriorating stored procedure running timesHow to use PIVOT here?How to create sums/counts of grouped items over multiple tablesSQL Server 2016 concurrency limitations? Tuning for db concurrencyNeed help in PivotTips on reshaping data, pivot-like?Dynamic dates PivotPivot data type error
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
Is it possible to group by elements (as in COLUMN LIKE='Value%') in a PIVOT table? I have a table [DBT].[Status] which contains various statuses (of databases, instances, etc.) and don't want to pivot/query all the PROD and TEST values as single values, but group them.
E.g. Instead of having columns for the statuses Prod, Prod ACC, Prod APP, .. etc. I would have only one column containing the values for Name LIKE 'Prod%' and Name LIKE 'Test%'.
What I have so far:
Table Definition
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
Table Values
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')
The Pivoted Status Table
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
Output So Far
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<>fiddle
The dbfiddle so far.
Question
Instead of having multiple rows for the various Test... and Prod.... values, I would prefer to have them grouped, similar to the following:
DB Status | Test | Prod | Migrated | Offline | Reserved
--------------- | ---- | ---- | -------- | ------- | --------
Database Status | 4 | 4 | 1 | 1 | 1
I don't have any clue how to go about solving my question. (To be honest I only just grasped PIVOT yesterday after extensive trial and errors).
This question is loosely related to the question How to create sums/counts of grouped items over multiple tables I have already asked. The tables [DBT].[Instance] and [DBT].[Database] contain a column with the [StatusID] which corresponds to the table we are looking at now.
sql-server sql-server-2014 pivot
add a comment |
Is it possible to group by elements (as in COLUMN LIKE='Value%') in a PIVOT table? I have a table [DBT].[Status] which contains various statuses (of databases, instances, etc.) and don't want to pivot/query all the PROD and TEST values as single values, but group them.
E.g. Instead of having columns for the statuses Prod, Prod ACC, Prod APP, .. etc. I would have only one column containing the values for Name LIKE 'Prod%' and Name LIKE 'Test%'.
What I have so far:
Table Definition
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
Table Values
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')
The Pivoted Status Table
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
Output So Far
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<>fiddle
The dbfiddle so far.
Question
Instead of having multiple rows for the various Test... and Prod.... values, I would prefer to have them grouped, similar to the following:
DB Status | Test | Prod | Migrated | Offline | Reserved
--------------- | ---- | ---- | -------- | ------- | --------
Database Status | 4 | 4 | 1 | 1 | 1
I don't have any clue how to go about solving my question. (To be honest I only just grasped PIVOT yesterday after extensive trial and errors).
This question is loosely related to the question How to create sums/counts of grouped items over multiple tables I have already asked. The tables [DBT].[Instance] and [DBT].[Database] contain a column with the [StatusID] which corresponds to the table we are looking at now.
sql-server sql-server-2014 pivot
add a comment |
Is it possible to group by elements (as in COLUMN LIKE='Value%') in a PIVOT table? I have a table [DBT].[Status] which contains various statuses (of databases, instances, etc.) and don't want to pivot/query all the PROD and TEST values as single values, but group them.
E.g. Instead of having columns for the statuses Prod, Prod ACC, Prod APP, .. etc. I would have only one column containing the values for Name LIKE 'Prod%' and Name LIKE 'Test%'.
What I have so far:
Table Definition
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
Table Values
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')
The Pivoted Status Table
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
Output So Far
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<>fiddle
The dbfiddle so far.
Question
Instead of having multiple rows for the various Test... and Prod.... values, I would prefer to have them grouped, similar to the following:
DB Status | Test | Prod | Migrated | Offline | Reserved
--------------- | ---- | ---- | -------- | ------- | --------
Database Status | 4 | 4 | 1 | 1 | 1
I don't have any clue how to go about solving my question. (To be honest I only just grasped PIVOT yesterday after extensive trial and errors).
This question is loosely related to the question How to create sums/counts of grouped items over multiple tables I have already asked. The tables [DBT].[Instance] and [DBT].[Database] contain a column with the [StatusID] which corresponds to the table we are looking at now.
sql-server sql-server-2014 pivot
Is it possible to group by elements (as in COLUMN LIKE='Value%') in a PIVOT table? I have a table [DBT].[Status] which contains various statuses (of databases, instances, etc.) and don't want to pivot/query all the PROD and TEST values as single values, but group them.
E.g. Instead of having columns for the statuses Prod, Prod ACC, Prod APP, .. etc. I would have only one column containing the values for Name LIKE 'Prod%' and Name LIKE 'Test%'.
What I have so far:
Table Definition
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
Table Values
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')
The Pivoted Status Table
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
Output So Far
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<>fiddle
The dbfiddle so far.
Question
Instead of having multiple rows for the various Test... and Prod.... values, I would prefer to have them grouped, similar to the following:
DB Status | Test | Prod | Migrated | Offline | Reserved
--------------- | ---- | ---- | -------- | ------- | --------
Database Status | 4 | 4 | 1 | 1 | 1
I don't have any clue how to go about solving my question. (To be honest I only just grasped PIVOT yesterday after extensive trial and errors).
This question is loosely related to the question How to create sums/counts of grouped items over multiple tables I have already asked. The tables [DBT].[Instance] and [DBT].[Database] contain a column with the [StatusID] which corresponds to the table we are looking at now.
sql-server sql-server-2014 pivot
sql-server sql-server-2014 pivot
asked 9 hours ago
hot2usehot2use
9,1825 gold badges25 silver badges63 bronze badges
9,1825 gold badges25 silver badges63 bronze badges
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
SUM(CASE
For a limited number of Names you can use a SUM(CASE solution in this way:
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
If there is an extensive list of Names but only few of them must be rewritten you can maintain the PIVOT solution:
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 here
DYNAMIC QUERY
If you feel a bit lazy and don't want to write all column names, you can use a dynamic query:
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 here
add a comment |
I think it's important to strictly separate the two tasks you're trying to perform in one step here.
- Classification
- Transformation
For classifying the data, my instinct here is to recommend a lookup table to rigorously map records to a parent class. e.g.
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) ;
...where the seed record in StatusType (ID=1 for the Status.StatusTypeID default) is a placeholder record named "Unknown" or similar.
When the lookup data is seeded and base records are updated with the correct keys, you can pivot to your heart's content.
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;
Full dbfiddle
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "182"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f247411%2fis-it-possible-to-pivot-on-a-like-statement%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
SUM(CASE
For a limited number of Names you can use a SUM(CASE solution in this way:
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
If there is an extensive list of Names but only few of them must be rewritten you can maintain the PIVOT solution:
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 here
DYNAMIC QUERY
If you feel a bit lazy and don't want to write all column names, you can use a dynamic query:
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 here
add a comment |
SUM(CASE
For a limited number of Names you can use a SUM(CASE solution in this way:
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
If there is an extensive list of Names but only few of them must be rewritten you can maintain the PIVOT solution:
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 here
DYNAMIC QUERY
If you feel a bit lazy and don't want to write all column names, you can use a dynamic query:
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 here
add a comment |
SUM(CASE
For a limited number of Names you can use a SUM(CASE solution in this way:
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
If there is an extensive list of Names but only few of them must be rewritten you can maintain the PIVOT solution:
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 here
DYNAMIC QUERY
If you feel a bit lazy and don't want to write all column names, you can use a dynamic query:
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 here
SUM(CASE
For a limited number of Names you can use a SUM(CASE solution in this way:
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
If there is an extensive list of Names but only few of them must be rewritten you can maintain the PIVOT solution:
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 here
DYNAMIC QUERY
If you feel a bit lazy and don't want to write all column names, you can use a dynamic query:
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 here
answered 9 hours ago
McNetsMcNets
17.5k5 gold badges26 silver badges61 bronze badges
17.5k5 gold badges26 silver badges61 bronze badges
add a comment |
add a comment |
I think it's important to strictly separate the two tasks you're trying to perform in one step here.
- Classification
- Transformation
For classifying the data, my instinct here is to recommend a lookup table to rigorously map records to a parent class. e.g.
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) ;
...where the seed record in StatusType (ID=1 for the Status.StatusTypeID default) is a placeholder record named "Unknown" or similar.
When the lookup data is seeded and base records are updated with the correct keys, you can pivot to your heart's content.
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;
Full dbfiddle
add a comment |
I think it's important to strictly separate the two tasks you're trying to perform in one step here.
- Classification
- Transformation
For classifying the data, my instinct here is to recommend a lookup table to rigorously map records to a parent class. e.g.
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) ;
...where the seed record in StatusType (ID=1 for the Status.StatusTypeID default) is a placeholder record named "Unknown" or similar.
When the lookup data is seeded and base records are updated with the correct keys, you can pivot to your heart's content.
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;
Full dbfiddle
add a comment |
I think it's important to strictly separate the two tasks you're trying to perform in one step here.
- Classification
- Transformation
For classifying the data, my instinct here is to recommend a lookup table to rigorously map records to a parent class. e.g.
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) ;
...where the seed record in StatusType (ID=1 for the Status.StatusTypeID default) is a placeholder record named "Unknown" or similar.
When the lookup data is seeded and base records are updated with the correct keys, you can pivot to your heart's content.
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;
Full dbfiddle
I think it's important to strictly separate the two tasks you're trying to perform in one step here.
- Classification
- Transformation
For classifying the data, my instinct here is to recommend a lookup table to rigorously map records to a parent class. e.g.
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) ;
...where the seed record in StatusType (ID=1 for the Status.StatusTypeID default) is a placeholder record named "Unknown" or similar.
When the lookup data is seeded and base records are updated with the correct keys, you can pivot to your heart's content.
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;
Full dbfiddle
answered 8 hours ago
Peter VandivierPeter Vandivier
2,1401 gold badge9 silver badges27 bronze badges
2,1401 gold badge9 silver badges27 bronze badges
add a comment |
add a comment |
Thanks for contributing an answer to Database Administrators Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f247411%2fis-it-possible-to-pivot-on-a-like-statement%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown