Michael Rowley
Michael Rowley

Reputation: 667

sql query different column based on input

I am using MS-SQL 2008. I have a table with different columns based on locations in it that will have a 'Y' or Null value. The table also has other data other than location from survey results. I have set up a temptable @TempLocation to hold the location based on the one or all. I need to select rows from the table based on 'Y' from one or more location rows within a date range.

TableID Northwest Northeast Southwest Southeast Batchno first_choice date_completed
1       Y                   Y         Y         1       A            2012-11-10
2                 Y                   Y         1       SA           2012-19-10       
3       Y         Y                             1       N            2012-07-10
4       Y         Y                   Y         2       A            2012-10-10
5                           Y                   2       A            2012-16-10
6       Y                             Y         2       D            2012-21-10
7                 Y                             NULL    A            2012-19-10
8       Y         Y         Y         Y         3       SA           2012-11-10
9       Y                                       3       A            2012-10-10
10                          Y         Y         3       A            2012-07-10  

I have created a Dynamic SQL statement to pull one location successfully but is it possible to pull all of them?

select  ''' + (SELECT * FROM @TempLocation) + ''',
count(batchno),
count(case when first_choice is not null then batchno end),
count(case when t.First_choice =''SD'' then 1 end) ,
count(case when t.First_choice=''D'' then 1 end) ,
count(case when t.First_choice=''N'' then 1 end) ,
count(case when t.First_choice=''A'' then 1 end) ,
count(case when t.First_choice=''SA'' then 1 end) 
from    customer_satisfaction_survey t
where   t.date_completed>= ''' + CAST(@beg_date AS VARCHAR) + '''
and     t.date_completed < ''' + CAST(dateadd(day,1,@end_date) AS Varchar) + '''
and     t.' + (SELECT * FROM @TempLocation) + ' = ''Y'''

An All result would look like this.

Number  Location   Total  Total2  SA  A  N  D  SD
1       Northwest  6      6       1   3  1  1  0
2       Northeast  5      4       2   2  1  0  0
3       Southwest  4      4       1   3  0  0  0
4       Southeast  6      6       2   3  0  1  0

Upvotes: 0

Views: 936

Answers (1)

Gordon Linoff
Gordon Linoff

Reputation: 1270401

I have to think that you are approaching this in the wrong way, because your data is not normalized. The first thing you should do is to normalize the data using UNPIVOT. I'm assuming that you are using SQL Server, since your syntax suggests that. It is a good idea to tag all questions with the database, though.

You can unpivot your data with a statement such as:

select BatchNo, FirstChoice, DateCompleted, Location
from d
unpivot (val for location in (Northwest, Northeast, Southwest, Southeast)) as unpvt

Next, set up your temporary table to have a separate row for each location. Then, you can do the join with no dynamic SQL. Something like:

with dnorm as (
    THE NORMALIZATION QUERY HERE
)
select dnorm.location, count(*) as total,
       sum(case when dnorm.first_choice is not null then 1 else 0 end) as total2,
       sum(case when dnorm.first_choice = 'SA' then 1 else 0 end) as SA,
       . . .
from dnorm join
     @TempLocation tl
     on dnorm.location = tl.location
where ALL YOUR WHERE CONDITIONS HERE

The final query looks something like:

with dnorm as (
    select BatchNo, FirstChoice, DateCompleted, Location
    from d
    unpivot (val for location in (Northwest, Northeast, Southwest, Southeast)) as unpvt
)
select dnorm.location, count(*) as total,
       sum(case when dnorm.first_choice is not null then 1 else 0 end) as total2,
       sum(case when dnorm.first_choice = 'SA' then 1 else 0 end) as SA,
       . . .
from dnorm join
     @TempLocation tl
     on dnorm.location = tl.location
where ALL YOUR WHERE CONDITIONS HERE  

The dynamic SQL approach is quite clever, but I don't think it is the simplest way to approach this.

Upvotes: 2

Related Questions