Sorting data by YEAR - sql

I am completely new to SQL and have really only run statements with minimal modifications. I am currently trying to modify this specific query:
SELECT DISTINCT (ROUND (windspeed * 2, -1) / 2) AS wndspd,
SUM (CASE WHEN month = 1 THEN 1 ELSE NULL END) AS January,
SUM (CASE WHEN month = 2 THEN 1 ELSE NULL END) AS February,
SUM (CASE WHEN month = 3 THEN 1 ELSE NULL END) AS March,
SUM (CASE WHEN month = 4 THEN 1 ELSE NULL END) AS April,
SUM (CASE WHEN month = 5 THEN 1 ELSE NULL END) AS May,
SUM (CASE WHEN month = 6 THEN 1 ELSE NULL END) AS June,
SUM (CASE WHEN month = 7 THEN 1 ELSE NULL END) AS July,
SUM (CASE WHEN month = 8 THEN 1 ELSE NULL END) AS August,
SUM (CASE WHEN month = 9 THEN 1 ELSE NULL END) AS September,
SUM (CASE WHEN month = 10 THEN 1 ELSE NULL END) AS October,
SUM (CASE WHEN month = 11 THEN 1 ELSE NULL END) AS November,
SUM (CASE WHEN month = 12 THEN 1 ELSE NULL END) AS December
FROM table1
WHERE platformid = 'coollocation'
AND networktype = 'typeofcoollocation'
AND (windspeedqc <> '2' OR windspeedqc IS NULL)
GROUP BY ROUND (windspeed * 2, -1) / 2
ORDER BY ROUND (windspeed * 2, -1) / 2;
What I want from the query is to instead of sorting by months, sort by all the years that are available for the specific location (platformid). So far I have just modified the script so that it looks like this:
SELECT DISTINCT
(ROUND (windspeed * 2, -1) / 2) AS wndspd,
SUM (
CASE
WHEN TO_CHAR (observationtime, 'YYYY') = 1957 THEN 1
ELSE NULL
END)
AS given_year,
SUM (
CASE
WHEN TO_CHAR (observationtime, 'YYYY') = 1958 THEN 1
ELSE NULL
END)
AS GIVEN_YEAR2
FROM table1
WHERE platformid = 'coollocation'
AND networktype = 'typeofcoollocation'
AND (windspeedqc <> '2' OR windspeedqc IS NULL)
GROUP BY ROUND (windspeed * 2, -1) / 2
ORDER BY ROUND (windspeed * 2, -1) / 2;
The problem is that I know that the years go from 1957-2015. I'm pretty sure that there is a more efficient way to list out the information that I want without creating a specific SUM string for every single year. I have no idea how to do that however. Please help!

You can try creating a PIVOT query
SELECT wndspd, [1957], [1958], [1959],...etc....[2013], [2014], [2015] FROM
(
SELECT (ROUND (windspeed * 2, -1) / 2) AS wndspd,
YEAR(observationtime) yr
FROM table1
WHERE platformid = 'coollocation'
AND networktype = 'typeofcoollocation'
AND (windspeedqc <> '2' OR windspeedqc IS NULL)
) src
PIVOT (
COUNT(yr)
FOR yr IN ([1957],[1958], [1959],...etc....[2013], [2014], [2015])
) pvt
you'll have to fill in all of the other years between 1959 and 2013.
here's an easier way to create all of the columns from 1957 to the current year.
DECLARE #PivotCols VARCHAR(MAX),
#MinYear INT = 1957,
#CurYear INT = YEAR(GETDATE())
WHILE #MinYear < #CurYear
BEGIN
SET #PivotCols = COALESCE( #PivotCols + '],[', '[') + CONVERT(VARCHAR, #MinYear)
SET #MinYear = #MinYear + 1
END
SET #PivotCols = CONCAT(#PivotCols,'],[',CONVERT(VARCHAR, #MinYear),']')
DECLARE #Sql VARCHAR(MAX) = '
SELECT wndspd, ' + #PivotCols + ' FROM
(
SELECT (ROUND (windspeed * 2, -1) / 2) AS wndspd,
YEAR(observationtime) yr
FROM table1
WHERE platformid = ''coollocation''
AND networktype = ''typeofcoollocation''
AND (windspeedqc <> ''2'' OR windspeedqc IS NULL)
) src
PIVOT (
COUNT(yr)
FOR yr IN (' + #PivotCols + ')
) pvt
'
EXEC (#Sql)

I think you are essentially trying to do this:
SELECT DISTINCT (ROUND (windspeed * 2, -1) / 2) AS wndspd
,TO_CHAR(observationtime, 'YYYY') as year,
,COUNT(1) as occurrences
FROM table1
WHERE platformid = 'coollocation'
AND networktype = 'typeofcoollocation'
AND (windspeedqc <> '2' OR windspeedqc IS NULL)
GROUP BY (ROUND(windspeed * 2, -1) / 2), TO_CHAR(observationtime, 'YYYY')
ORDER BY 1, 2;
...however the count of occurrences in each year would then be represented by a row instead of a column.
Unfortunately there is no easy way to pivot the rows in this query into columns because you fundamentally need to know how many columns there are and ensure each row has the values populated properly.
At the end of the day you'll need to add a line for each year to your SELECT clause. It could look like this:
SELECT yearly.wndspd
,SUM(CASE WHEN yearly.year='1957' THEN yearly.occurrences ELSE 0 END) as 1957
,SUM(CASE WHEN yearly.year='1958' THEN yearly.occurrences ELSE 0 END) as 1958
...
,SUM(CASE WHEN yearly.year='2015' THEN yearly.occurrences ELSE 0 END) as 2015
FROM
(SELECT DISTINCT (ROUND (windspeed * 2, -1) / 2) AS wndspd
,TO_CHAR(observationtime, 'YYYY') as year,
,COUNT(1) as occurrences
FROM table1
WHERE platformid = 'coollocation'
AND networktype = 'typeofcoollocation'
AND (windspeedqc <> '2' OR windspeedqc IS NULL)
GROUP BY (ROUND(windspeed * 2, -1) / 2), TO_CHAR(observationtime, 'YYYY')) yearly
GROUP BY yearly.wndspd
ORDER BY 1, 2;

Related

SQL Query - Case When Min - Closest date to today

I have a table with a list of Customer Agreements [source.Agreements].
A Customer can have multiple Agreements with different [Agreement End Date]
I need to get the closest [Agreement End Date] and then assign it to an [Agreement Window]
For Example:
If between Jan - Jun then:
[Agreement Window] = FY H2
If between Jul - Dec then:
[Agreement Window] = FY H1.
The financial year is = ([Agreement End Date] - 1 year)
Example:
ID has [Agreement End Date] = 2020-06-30. So, the [Agreement Window] = 'FY19 H2'.
However, when an ID has more than one [Agreement End Date], and the second date is between July - December, it uses that date and not the MIN date.
Example: (see image below)
ID 1789 has three [Agreement End Date] = '2018-05-31', '2018-09-30', '2019-03-30'.
It should return:
FY17 H2
but it returns
FY17 H1
I've included the query I have tried below. I think I need a second MIN statement but not sure how to do it with a CASE statement.
DECLARE #dtDate DATE
SET #dtDate = GETDATE();
select A.ID
,min(case when AgreementEndDate>=#dtDate then AgreementEndDate else '' end) as 'Agreement End Date'
,min(case when AgreementEndDate>=#dtDate and ((month(AgreementEndDate) >= 7 and month(AgreementEndDate) <= 12)) THEN 'FY' + convert(varchar(2),(FORMAT(AgreementEndDate, 'yy') - 1)) + ' H1'
when AgreementEndDate>=#dtDate and ((month(AgreementEndDate) >= 1 and month(AgreementEndDate) <= 6)) THEN 'FY' + convert(varchar(2),(FORMAT(AgreementEndDate, 'yy') - 1)) + ' H2'
else null end) as 'Agreement Window'
from source.Agreements A
where A.ID IN ('1740','1789','7582645','2387732')
group by A.ID
How about this:
DECLARE #dtDate DATE
SET #dtDate = GETDATE();
WITH cte
AS (
SELECT *, ROW_NUMBER() OVER (
PARTITION BY ID ORDER BY AgreementEndDate ASC
) AS RowNum
FROM [source].[dbo].Agreements A
WHERE A.ID IN ('1740', '1789', '7582645', '2387732')
)
SELECT ID
, CASE WHEN AgreementEndDate >= #dtDate THEN AgreementEndDate ELSE '' END AS 'Agreement End Date'
, CASE WHEN AgreementEndDate >= #dtDate AND ((month(AgreementEndDate) >= 7 AND month(AgreementEndDate) <= 12)) THEN 'FY' + convert(VARCHAR(2), (FORMAT(AgreementEndDate, 'yy') - 1)) + ' H1'
WHEN AgreementEndDate >= #dtDate AND ((month(AgreementEndDate) >= 1 AND month(AgreementEndDate) <= 6)) THEN 'FY' + convert(VARCHAR(2), (FORMAT(AgreementEndDate, 'yy') - 1)) + ' H2'
ELSE NULL
END AS 'Agreement Window'
FROM cte
WHERE RowNum = 1
The content of the table and result as shown:

How to show monthly data even if there are no results yet SQL Server 2008

So I wrote a script that would show monthly premium. Say if you want to view the total premium up to November, you can pass through a parameter in in SSRS to pick 1/1/2016 - 11/30/2016. This would only show the data up until november, hoever, I would like to show it up until december even if there are no records there. How do I go about doing this in SQL? Here is my script so far:
SELECT lc.[Date]
,lc.Carrier
,lc.[Direct Ceded Written Premium]
,cast(cast(year(lc.[date]) as varchar(4)) + '-' + cast(month(lc.[date]) as varchar(2)) + '-01' as date) as [begofmonth]
from
(
SELECT
CASE
WHEN pd.TransactionEffDate < pd.TransactionDate THEN cast(pd.TransactionDate as DATE)
WHEN pd.TransactionEffDate < pd.EffectiveDate THEN cast(pd.EffectiveDate as DATE)
ELSE cast(pd.TransactionEffDate as date)
END AS [Date]
,CASE WHEN LEFT(PD.POLICYNUM, 3) = 'ORV'
THEN 'Palomar Value Select OR'
WHEN LEFT(PD.POLICYNUM, 3) = 'VSE'
THEN 'Palomar Value Select CA'
WHEN LEFT(PD.POLICYNUM, 3) = 'WAV'
THEN 'Palomar Value Select WA'
ELSE 'Palomar' END AS [Carrier]
,ISNULL(SUM(pd.WrittenPremium), 0) AS [Direct Ceded Written Premium]
FROM premdetail pd
JOIN transactionpremium tp ON pd.systemid = tp.systemid
AND pd.transactionpremiumid = tp.id
JOIN transactionhistory th ON tp.systemid = th.systemid
AND tp.cmmcontainer = th.cmmcontainer
AND tp.parentid = th.id
JOIN basicpolicy bp ON th.systemid = bp.systemid
AND th.cmmcontainer = bp.cmmcontainer
AND th.parentid = bp.id
WHERE
(CASE
WHEN pd.TransactionEffDate < pd.TransactionDate THEN pd.TransactionDate
WHEN pd.TransactionEffDate < pd.EffectiveDate THEN pd.EffectiveDate
ELSE pd.TransactionEffDate
END) > = CAST(#StartDate AS DATE)
AND (CASE
WHEN pd.TransactionEffDate < pd.TransactionDate THEN pd.TransactionDate
WHEN pd.TransactionEffDate < pd.EffectiveDate THEN pd.EffectiveDate
ELSE pd.TransactionEffDate
END) < CAST(#EndDate + 1 AS DATE)
AND (bp.carriercd = #ResEQCarrierCd
OR #ResEQCarrierCd = 'All')
GROUP BY
CASE
WHEN pd.TransactionEffDate < pd.TransactionDate THEN cast(pd.TransactionDate as DATE)
WHEN pd.TransactionEffDate < pd.EffectiveDate THEN cast(pd.EffectiveDate as DATE)
ELSE cast(pd.TransactionEffDate as date)
END
,CONVERT(VARCHAR, pd.EffectiveDate, 101)
,CONVERT(VARCHAR, pd.ExpirationDate, 101)
,CASE
WHEN LEFT(PD.POLICYNUM, 3) = 'ORV'
THEN 'Palomar Value Select OR'
WHEN LEFT(PD.POLICYNUM, 3) = 'VSE'
THEN 'Palomar Value Select CA'
WHEN LEFT(PD.POLICYNUM, 3) = 'WAV'
THEN 'Palomar Value Select WA'
ELSE 'Palomar'
END
,CASE
WHEN pd.TransactionCode = 'EN' THEN CONVERT(VARCHAR, th.TransactionEffectiveDt, 101)
ELSE ''
END
,CONVERT(VARCHAR, DATEADD(ms, -3, DATEADD(mm, DATEDIFF(m, 0, th.transactiondt) + 1, 0)), 101)
,CASE
WHEN pd.TransactionEffDate < CAST(CONVERT(VARCHAR, pd.TransactionDate, 101) AS SMALLDATETIME) THEN CONVERT(VARCHAR, pd.TransactionDate, 101)
WHEN pd.TransactionEffDate < pd.EffectiveDate THEN CONVERT(VARCHAR, pd.EffectiveDate, 101)
ELSE CONVERT(VARCHAR, pd.TransactionEffDate, 101)
END
) lc
ORDER BY lc.[Date], lc.[Carrier], lc.[Direct Ceded Written Premium]
With the parameter that I have, it would only show up until November. However, I would like it to show the whole year, up to December at in this case, even if there are no data there since I didn't pick the enddate variable to be december. I attached an example screenshot of what it should look like when exported to excel.
Just to give you an idea:
declare #tbl TABLE(ID INT IDENTITY,SomeValue VARCHAR(100),SomeDate DATE);
INSERT INTO #tbl VALUES('Some date in March',{d'2016-03-05'}),('Some date in June',{d'2016-06-30'});
WITH AllMonths AS
(
SELECT 1 AS MonthIndex
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9
UNION ALL SELECT 10
UNION ALL SELECT 11
UNION ALL SELECT 12
)
SELECT MonthIndex
,t.*
FROM AllMonths
LEFT JOIN #tbl AS t ON MONTH(t.SomeDate)=MonthIndex
The result
1 NULL NULL NULL
2 NULL NULL NULL
3 1 Some date in March 2016-03-05
4 NULL NULL NULL
5 NULL NULL NULL
6 2 Some date in June 2016-06-30
7 NULL NULL NULL
8 NULL NULL NULL
9 NULL NULL NULL
10 NULL NULL NULL
11 NULL NULL NULL
12 NULL NULL NULL
There are many ways to create a tally table
CTE with ROW_NUMBER()
A list like in my example
A physical table
It is a good idea to maintain a numbers/DATE table!
In a previous answer I showed one way to create such a table.

Generate Monthly based records in a period

Here is my query to retreive the report for each month to get the paid and unpaid bookings
SELECT tbc.tbcId
,tbc.tbcName
,(
SELECT COUNT(bb.bbId)
FROM MyBooking bb
WHERE bb.tbcId = tbc.tbcId
AND bb.bbIsPayed = 1
AND Year(bb.bbDate) = '2016' --proc parameter #year
AND Month(bb.bbDate) = '7' --proc parameter #month
) AS PaidCount
,(
SELECT SUM(CASE
WHEN bb.bbVAT = 1
THEN (bb.bbPrice / 100) * 80
ELSE bb.bbPrice
END)
FROM MyBooking bb
WHERE bb.tbcId = tbc.tbcId
AND bb.bbIsPayed = 1
AND Year(bb.bbDate) = '2016' --proc parameter #year
AND Month(bb.bbDate) = '7' --proc parameter #month
) AS PaidAmount
,(
SELECT COUNT(bb.bbId)
FROM MyBooking bb
WHERE bb.tbcId = tbc.tbcId
AND bb.bbIsPayed <> 1
AND Year(bb.bbDate) = '2016' --proc parameter #year
AND Month(bb.bbDate) = '7' --proc parameter #month
) AS UnpaidCount
,(
SELECT SUM(CASE
WHEN bb.bbVAT = 1
THEN (bb.bbPrice / 100) * 80
ELSE bb.bbPrice
END)
FROM MyBooking bb
WHERE bb.tbcId = tbc.tbcId
AND bb.bbIsPayed <> 1
AND Year(bb.bbDate) = '2016' --proc parameter #year
AND Month(bb.bbDate) = '7' --proc parameter #month
) AS UnPaidAmount
FROM BookingCategories tbc
WHERE tbc.tbcIncludeReport = 1
AND tbc.tbcId IN (
SELECT DISTINCT con.tbcId
FROM CategoryXTags con
WHERE (
con.ttId = 26
OR con.ttId = 23
OR con.ttId = 24
)
)
ORDER BY tbc.tbcName ASC;
I have to run this for a given period of time, example Jan 2016 to Aug 2016.
As of now I run this in a loop by passing a #year and #month variable.
Is it possible to just pass #FromDate and #Todate and generate the report for each month in a same query? I couldnt able to think much in SQL to achieve this.
Untested, but I think will shrink your process down
Declare #Date1 Date = '2016-01-01'
Declare #Date2 Date = '2016-08-31'
Select Period = EOMonth(bb.bbDate)
,tbc.tbcId
,tbc.tbcName
,PaidCount = sum(case when bb.bbIsPayed=1 then 1 else 0 end)
,PaidAmount = sum(case when bb.bbIsPayed=1 and 1bb.bbVAT = 1 Then (bb.bbPrice / 100) * 80 ELSE bb.bbPrice end)
,UnpaidCount = sum(case when bb.bbIsPayed<>1 then 1 else 0 end)
,UnPaidAmount = sum(case when bb.bbIsPayed <> 1 and bb.bbVAT = 1 Then (bb.bbPrice / 100) * 80 ELSE bb.bbPrice end)
From BookingCategories tbc
Join MyBooking bb on (bb.bbId = tbc.tbcId)
Where tbc.tbcIncludeReport = 1
and tbc.tbcId IN (26,26,24)
and bb.bbDate between #Date1 and #Date2
Group By
EOMonth(bb.bbDate)
,tbc.tbcId
,tbc.tbcName
Order By 1,tbc.tbcName ASC

Update multiple variables in a single query

I have a table with Sum of Amounts for Each Weekday (Sunday to Saturday) . Table structure is as below.
I need to assign these table values into parameters. For E.g : I need to assign sum of rdate '2015-11-15' i.e 324 to a variable #sundayval , 374 to variable #mondayval etc...
How to do this In a single update query. I have tried out with Case statement,
But it only assigns value to variable #saturdayval .
Thanks for the Help.
This does the job. It doesn't depend on any particulat DATEFIRST settings - it instead uses an arbitrarily chosen sunday (I picked 17th May this year) (what I usually refer to as a "known good" date because it has the property we're looking for, in this case the right day of the week):
declare #t table ([sum] int not null,rdate datetime2 not null)
insert into #t([sum],rdate) values
(324,'20151115'),
(374,'20151116'),
(424,'20151117'),
(474,'20151118'),
(524,'20151119'),
(574,'20151120'),
(624,'20151121')
declare #sundayval int
declare #mondayval int
declare #tuesdayval int
declare #wednesdayval int
declare #thursdayval int
declare #fridayval int
declare #saturdayval int
select
#sundayval = SUM(CASE WHEN DATEPART(weekday,rdate) = DATEPART(weekday,'20150517') THEN [sum] END),
#mondayval = SUM(CASE WHEN DATEPART(weekday,rdate) = DATEPART(weekday,'20150518') THEN [sum] END),
#tuesdayval = SUM(CASE WHEN DATEPART(weekday,rdate) = DATEPART(weekday,'20150519') THEN [sum] END),
#wednesdayval = SUM(CASE WHEN DATEPART(weekday,rdate) = DATEPART(weekday,'20150520') THEN [sum] END),
#thursdayval = SUM(CASE WHEN DATEPART(weekday,rdate) = DATEPART(weekday,'20150521') THEN [sum] END),
#fridayval = SUM(CASE WHEN DATEPART(weekday,rdate) = DATEPART(weekday,'20150522') THEN [sum] END),
#saturdayval = SUM(CASE WHEN DATEPART(weekday,rdate) = DATEPART(weekday,'20150523') THEN [sum] END)
from #t
select #sundayval,#mondayval,#tuesdayval,#wednesdayval,#thursdayval,#fridayval,#saturdayval
Result:
----------- ----------- ----------- ----------- ----------- ----------- -----------
324 374 424 474 524 574 624
Ok - let's do it this way: the else case is set to return itself, so each variable essentially aggregates as a coalesce. Note: I don't have any way to test this right now. :)
SELECT
#sundayval = case when DATEPART(weekday, rdate) = 1 then sum else #sundayval end
, #mondayval = case when DATEPART(weekday, rdate) = 2 then sum else #mondayval end
, #tuesdayval = case when DATEPART(weekday, rdate) = 3 then sum else #tuesdayval end
, #wednesdayval = case when DATEPART(weekday, rdate) = 4 then sum else #wednesdayval end
, #thursdayval = case when DATEPART(weekday, rdate) = 5 then sum else #thursdayval end
, #fridayval = case when DATEPART(weekday, rdate) = 6 then sum else #fridayval end
, #saturdayval = case when DATEPART(weekday, rdate) = 7 then sum else #saturdayval end
FROM TABLE
I have No idea Whether a Single UPDATE Statement will do this. I have assigned value for Each Variable like as Below,
SELECT #SunTotal = [sum]
FROM [table]
where rdate = #Startdate
SELECT #MonTotal = [sum]
FROM [table]
where rdate = DATEADD(DAY,1,#Startdate)
SO ON...

SQL Comma Separated List from Multiple Columns

I have data that looks like this:
CUSTOMER_ID OPERDAYSJUL OPERDAYSAUG OPERDAYSSEP ... OPERDAYSJUN
1 30 15 2
2 5 1 0
3 6 0 12
4 12 5 23
For each customer_id, I want a comma-delimited list indicating which months the customer operates:
CUSTOMER_ID OPERATING_MONTHS
1 Jul, Aug, Sep
2 Jul, Aug
3 Jul, Sep
4 Jul, Aug, Sep
and so forth. How might I use SQL Server 2005 SQL (not T-SQL) to easily produce this comma-delimited list?
Most solutions I see here on Stack Overflow and elsewhere seem to create comma-separated lists based on joining multiple rows values, not column values:
T-SQL
FOR XML PATH('')
Correlated subquery combined with REPLACE/STUFF/SUBSTRING
Am I missing something obvious? Thanks in advance for assistance or pointer to appropriate existing solution here.
This strips off the extra comma
SELECT
CUSTOMER_ID,
SUBSTRING(
CASE WHEN OPERDAYSJUL > 0 THEN ', Jul' ELSE '' END +
CASE WHEN OPERDAYSAUG > 0 THEN ', Aug' ELSE '' END +
...
CASE WHEN OPERDAYSJUN > 0 THEN ', Jun' ELSE '' END,
3, 255)
FROM TheTable
declare #t table (CUSTOMER_ID int
, OPERDAYSJUL int
, OPERDAYSAUG int
, OPERDAYSSEP int
-- ... rest of 9 months here
);
insert into #t (CUSTOMER_ID, OPERDAYSJUL, OPERDAYSAUG, OPERDAYSSEP)
select 1, 30, 15, 22 union all
select 2, 0, 10, 10 union all
select 3, 0, 0, 10 union all
select 4, 0, 0, 0 union all
select 5, 10, 0, 10 union all
select 6, 10, 10, 0 union all
select 7, 0, 10, 0 union all
select 8, 10, 0, 0;
with cte_months as (
select CUSTOMER_ID
, case when OPERDAYSJUL=0 then '' else ', Jul' end
+ case when OPERDAYSAUG=0 then '' else ', Aug' end
+ case when OPERDAYSSEP=0 then '' else ', Sep' end
-- ... rest of 9 months here
as month_list
from #t)
select CUSTOMER_ID, substring(month_list, 3, 70)
from cte_months;
You can do something like this.
CONCAT(CASE OPERDAYSJUL > 0 THEN "Jul," ELSE "" END,CASE OPERDAYSAUG > 0 THEN "Aug" ELSE "" END ... )
Assuming your table has 13 columns (1 for each month of the year + CUSTOMER_ID), you can write something like:
SELECT
CUSTOMER_ID,
CASE OPERDAYSJUL > 0 THEN 'Jul,' ELSE '' END +
CASE OPERDAYSAUG > 0 THEN 'Aug,' ELSE '' END +
...
FROM MyTable
and build up a string that represents your comma-separated list using CASE statements, one for each month.
select
customer_id,
case when len(operating_month) > 0 then
left(operating_month, len(operating_month) - 1)
else
operating_month
end as operating_month
from
(
SELECT CUSTOMER_ID,
CASE OPERDAYSJUL > 0 THEN 'Jul,' ELSE '' END
+ CASE OPERDAYSAUG > 0 THEN 'Aug,' ELSE '' END
+ ...
as operating_month
FROM MyTable
) as x