Pergunta

I want to have a query which dynamically chooses the column to group by.

Suppose I have this table:

Sample Table

I want to see the results grouped by a variable:

Declare @grouBy varchar(50)
Set @grouBy = 'name' -- or 'job' or 'jobCode'

I wrote a query:

SELECT MIN(Name), MIN(job), MIN(jobCode), MAX(salary)
FROM TempTable
GROUP BY
    Name,
    CASE
        WHEN @grouBy = 'job' THEN job
        WHEN @grouBy = 'jobCode' THEN jobCode
    END

It errors saying:

Conversion failed when converting the varchar value 'programmer' to data type int.

My question is how does the data type matter in this grouping?

I also tried to put the CASE in the SELECT statement but got the following error:

Column '....' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

Nenhuma solução correta

Outras dicas

You need to settle on a common data type for the columns that you are essentially merging in the CASE.

A job value like 'programmer' cannot be converted to an int of course.

Explicitly cast jobCode to job's string data type then. For example, if job's data type is nvarchar(50), use something like this:

Declare @grouBy varchar(50)
Set @grouBy = 'job' -- or 'name' or 'jobCode'

Select 
    min(Name), min(job), min(jobCode), max(salary)
from TempTable
-- FORNOW: for quick testing/debugging
--from (
--    select 'whatever' as Name, 'a' as job, 1 as jobCode, 1000 as salary
--    union
--    select 'who cares', 'b', 2, 2000) t
Group by Name,
Case 
    when @grouBy = 'job' then job
    when @grouBy = 'jobCode' then cast(jobCode as nvarchar(50))
End

/* FORNOW: quick testing/debugging results
(No column name)    (No column name)    (No column name)    (No column name)
whatever            a                       1                       1000
who cares           b                       2                       2000
*/

You can use IF clause

IF(@groupBy = 'job')
Begin
  SELECT
        Name, job,min(jobCode), max(salary)s
  from TempTable
  Group by Name,@grouBy 
End

Else If(@groupBy = 'jobCode')
Begin
  SELECT
        Name, jobCode,min(job), max(salary)s
  from TempTable
  Group by Name,@grouBy 
End

After juggling around the code,
i found optional "Group By" working with columns having different datatypes.
in this method there is no need to CAST() your columns.

1. Simple Example

Declare @groupBy varchar(50)
Set @groupBy = 'name' -- or 'name' or 'jobCode'
Select
      min(Name), min(job), min(jobCode), max(salary)
from TempTable
Group by
    Case when @groupBy = 'name' then name End,
    Case when @groupBy = 'job' then job End,
    Case when @groupBy = 'jobCode' then jobCode End

2. And For more aggregate functions in "Select clause" you can use like this.

Select
    Case
        when @grouBy = 'Name' then min(Name)
        when @grouBy = 'job' then count(Name)
        when @grouBy = 'jobCode' then count(Name)
    End as Name
    , max(Salary) as Salary
From TempTable
Group by
    Case when @groupBy = 'name' then name End,
    Case when @groupBy = 'job' then job End,
    Case when @groupBy = 'jobCode' then jobCode End



Thank you J0e3gan and mhasan for your efforts.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top