|
|
|
SSC-Enthusiastic
      
Group: General Forum Members
Last Login: 2 days ago @ 3:26 AM
Points: 156,
Visits: 567
|
|
Hi geniuses,
It is possible to have a 'GROUP BY' inside a CASE Statement? In order to Sum my values properly? What I got so far:
CASE WHEN KTVID = '12345' AND KTVValueType = '02.KTVSCHAF' THEN Value ELSE 0 END
Thanks Regards
|
|
|
|
|
SSCrazy Eights
        
Group: General Forum Members
Last Login: Yesterday @ 2:33 PM
Points: 8,620,
Visits: 8,261
|
|
|
|
|
|
SSCrazy
      
Group: General Forum Members
Last Login: 2 days ago @ 2:19 PM
Points: 2,037,
Visits: 3,761
|
|
This article may help http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/17a6c4f4-3a44-4d72-89e4-37c3ab9df532
______________________________________________________________________________ "Never argue with an idiot; They'll drag you down to their level and beat you with experience"
|
|
|
|
|
SSC Veteran
      
Group: General Forum Members
Last Login: Tuesday, May 21, 2013 7:19 AM
Points: 283,
Visits: 1,239
|
|
You can avoid group by altogether by using the OVER() method when using aggregates (I think this is for SQL2008 and higher).
IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL DROP TABLE #TempTable
CREATE TABLE #TempTable ( [ID] INT IDENTITY(1,1) NOT NULL, [Age] INT NULL, [Sex] CHAR(1) NULL, [School] VARCHAR(20) NULL, PRIMARY KEY (ID))
INSERT INTO #TempTable SELECT 22,'M','Thomasville' UNION SELECT 19,'M','Thomasville' UNION SELECT 31,'F','Polytechnic' UNION SELECT 20,'M','Thomasville' UNION SELECT 32,'F','Polytechnic' UNION SELECT 27,'F','Thomasville' UNION SELECT 22,'M','Polytechnic' UNION SELECT 18,'M','Thomasville' UNION SELECT 40,'F','Thomasville'
SELECT * FROM #TempTable
DECLARE @Category VARCHAR(50) SET @Category = 'Sex'
SELECT DISTINCT (CASE WHEN @Category = 'Sex' THEN Sex WHEN @Category = 'School' THEN School END) AS Category ,(CASE WHEN @Category = 'Sex' THEN MIN(Age) OVER (PARTITION BY Sex) WHEN @Category = 'School' THEN MIN(Age) OVER (PARTITION BY School) END) AS MinAge ,(CASE WHEN @Category = 'Sex' THEN AVG(Age) OVER (PARTITION BY Sex) WHEN @Category = 'School' THEN AVG(Age) OVER (PARTITION BY School) END) AS Average ,(CASE WHEN @Category = 'Sex' THEN MAX(Age) OVER (PARTITION BY Sex) WHEN @Category = 'School' THEN MAX(Age) OVER (PARTITION BY School) END) AS MaxAge FROM #TempTable
SET @Category = 'School'
SELECT DISTINCT (CASE WHEN @Category = 'Sex' THEN Sex WHEN @Category = 'School' THEN School END) AS Category ,(CASE WHEN @Category = 'Sex' THEN MIN(Age) OVER (PARTITION BY Sex) WHEN @Category = 'School' THEN MIN(Age) OVER (PARTITION BY School) END) AS MinAge ,(CASE WHEN @Category = 'Sex' THEN AVG(Age) OVER (PARTITION BY Sex) WHEN @Category = 'School' THEN AVG(Age) OVER (PARTITION BY School) END) AS Average ,(CASE WHEN @Category = 'Sex' THEN MAX(Age) OVER (PARTITION BY Sex) WHEN @Category = 'School' THEN MAX(Age) OVER (PARTITION BY School) END) AS MaxAge FROM #TempTable
Output all data:
ID Age Sex School 1 18 M Thomasville 2 19 M Thomasville 3 20 M Thomasville 4 22 M Polytechnic 5 22 M Thomasville 6 27 F Thomasville 7 31 F Polytechnic 8 32 F Polytechnic 9 40 F Thomasville
Output selected data:
Category MinAge Average MaxAge F 27 32 40 M 18 20 22
Category MinAge Average MaxAge Polytechnic 22 28 32 Thomasville 18 24 40
|
|
|
|
|
Ten Centuries
      
Group: General Forum Members
Last Login: 2 days ago @ 3:56 PM
Points: 1,324,
Visits: 1,778
|
|
You can use CASE w/i a GROUP BY.
You can also use CASE w/i a SUM to control which values get aggregated. For example:
SELECT a, b, SUM(CASE WHEN KTVID = '12345' AND KTVValueType = '02.KTVSCHAF' THEN Value ELSE 0 END) AS KTVID_12345_02_Total, SUM(Value) AS All_Values_Total FROM dbo.tablename GROUP BY a, b
SQL DBA,SQL Server MVP('07, '08, '09) One man with courage makes a majority. Andrew Jackson
|
|
|
|
|
SSC Veteran
      
Group: General Forum Members
Last Login: Tuesday, May 21, 2013 7:19 AM
Points: 283,
Visits: 1,239
|
|
There's really no limit to what you can do with grouping and case statements. The OVER() clause really makes thing easy. You can even combine all the aggregates in the same CASE statement, then use the DelimitedSplit8K function and a PIVOT to show the aggregated results:
IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL DROP TABLE #TempTable
CREATE TABLE #TempTable ( [ID] INT IDENTITY(1,1) NOT NULL, [Age] INT NULL, [Sex] CHAR(1) NULL, [School] VARCHAR(20) NULL, PRIMARY KEY (ID))
INSERT INTO #TempTable SELECT 22,'M','Thomasville' UNION SELECT 19,'M','Thomasville' UNION SELECT 31,'F','Polytechnic' UNION SELECT 20,'M','Thomasville' UNION SELECT 32,'F','Polytechnic' UNION SELECT 27,'F','Thomasville' UNION SELECT 22,'M','Polytechnic' UNION SELECT 18,'M','Thomasville' UNION SELECT 40,'F','Thomasville'
IF OBJECT_ID('tempdb..#ResultsTable') IS NOT NULL DROP TABLE #ResultsTable
CREATE TABLE #ResultsTable ( [ID] INT IDENTITY(1,1) NOT NULL, [Sex] VARCHAR(10) NULL, [SexMin] INT NULL, [SexAvg] DECIMAL(5,2) NULL, [SexMax] INT NULL, [School] VARCHAR(20) NULL, [SchMin] INT NULL, [SchAvg] DECIMAL(5,2) NULL, [SchMax] INT NULL, PRIMARY KEY (ID))
INSERT INTO #ResultsTable SELECT (CASE WHEN Sex = 'M' THEN 'Male' WHEN Sex = 'F' THEN 'Female' END ) AS Sex ,MAX(MinAge1) OVER (PARTITION BY Sex) AS SexMin ,MAX(CAST(AvgAge1 AS DECIMAL(5,2))) OVER (PARTITION BY Sex) AS SexAvg ,MAX(MaxAge1) OVER (PARTITION BY Sex) AS SexMax ,School ,MAX(MinAge2) OVER (PARTITION BY School) AS SchMin ,MAX(CAST(AvgAge2 AS DECIMAL(5,2))) OVER (PARTITION BY School) AS SchAvg ,MAX(MaxAge2) OVER (PARTITION BY School) AS SchMax FROM ( SELECT Sex ,(CASE WHEN ItemNumSex = 1 THEN 'MinAge1' WHEN ItemNumSex = 2 THEN 'AvgAge1' WHEN ItemNumSex = 3 THEN 'MaxAge1' END) AS AggTypeSex ,ItemSex AS AggAgeSex ,School ,(CASE WHEN ItemNumSch = 1 THEN 'MinAge2' WHEN ItemNumSch = 2 THEN 'AvgAge2' WHEN ItemNumSch = 3 THEN 'MaxAge2' END) AS AggTypeSch ,ItemSch AS AggAgeSch FROM ( SELECT R.Sex ,R.School ,ds1.ItemNumber AS ItemNumSex ,ds1.Item AS ItemSex ,ds2.ItemNumber AS ItemNumSch ,ds2.Item AS ItemSch FROM ( SELECT Sex ,School ,(CASE WHEN Sex IS NOT NULL THEN CAST(MIN(Age) OVER (PARTITION BY Sex) AS VARCHAR(10)) +','+CAST(AVG(CAST(Age AS DECIMAL(5,2))) OVER (PARTITION BY Sex) AS VARCHAR(10)) +','+CAST(MAX(Age) OVER (PARTITION BY Sex) AS VARCHAR(10)) END) AS AggSex ,(CASE WHEN School IS NOT NULL THEN CAST(MIN(Age) OVER (PARTITION BY School) AS VARCHAR(10)) +','+CAST(AVG(CAST(Age AS DECIMAL(5,2))) OVER (PARTITION BY School) AS VARCHAR(10)) +','+CAST(MAX(Age) OVER (PARTITION BY School) AS VARCHAR(10)) END) AS AggSchool FROM #TempTable ) AS R CROSS APPLY dbo.DelimitedSplit8K(R.AggSex,',') AS ds1 CROSS APPLY dbo.DelimitedSplit8K(R.AggSchool,',') AS ds2 ) AS R1 ) AS A PIVOT ( MAX(AggAgeSex) FOR AggTypeSex IN (MinAge1,AvgAge1,MaxAge1) ) AS SexAggregates PIVOT ( MAX(AggAgeSch) FOR AggTypeSch IN (MinAge2,AvgAge2,MaxAge2) ) AS SchAggregates
SELECT DISTINCT Sex AS Category ,SexMin AS AgeMin ,SexAvg AS AgeAvg ,SexMax AS AgeMax FROM #ResultsTable UNION ALL SELECT DISTINCT School AS Category ,SchMin AS AgeMin ,SchAvg AS AgeAvg ,SchMax AS AgeMax FROM #ResultsTable
Output:
Category AgeMin AgeAvg AgeMax Female 27 32.50 40 Male 18 20.20 22 Polytechnic 22 28.33 32 Thomasville 18 24.33 40
|
|
|
|