sql server - How To Shorten This SQL Query Without A Million AND/OR's? -


i have table 13 columns (one row id # , other 12 represent 1 each month of year). each column contain numbers , want write several queries check each row conditions , return id of rows match.

so far i've been fine writing basic select queries i'm getting bit stuck on writing select queries check multiple conditions @ once without writing million lines of code each time.

the current query i'm writing needs check each pair of consecutive months (e.g. jan/feb, feb/mar, etc) see how big difference between them , needs return rows 2 lots of consecutive months have > 20% difference between them , remaining pairs < 10% difference.

for example, if january 1000 , february 1300, that's 30% difference that's 1 lot. if april 1500 , may 2100, that's 40% difference there's 2nd lot. long every other pair (feb/mar, mar/apr, ..., nov/dec) < 10% difference each, row needs returned.

unfortunately, way can work manually checking every single possibility (which works) isn't re-useable writing similar queries.

here abbreviated version of i've got far:

select pkid dbo.tblmonthdata  ((colfeb > coljan * 1.2 , colmar > colfeb * 1.2) , (colapr < colmar * 1.1 , colmay < colapr * 1.1 , coljun < colmay * 1.1 , coljul < coljun * 1.1 , colaug < coljul * 1.1 , colsep < colaug * 1.1 , coloct < colsep * 1.1 , colnov < coloct * 1.1 , coldec < colnov * 1.1))  or ((colfeb > coljan * 1.2 , colapr > colmar * 1.2) , (colmar < colfeb * 1.1 , colmay < colapr * 1.1 , coljun < colmay * 1.1 , coljul < coljun * 1.1 , colaug < coljul * 1.1 , colsep < colaug * 1.1 , coloct < colsep * 1.1 , colnov < coloct * 1.1 , coldec < colnov * 1.1))  or ((colfeb > coljan * 1.2 , colmay > colapr * 1.2) , (colmar < colfeb * 1.1 , colapr < colmar * 1.1 , coljun < colmay * 1.1 , coljul < coljun * 1.1 , colaug < coljul * 1.1 , colsep < colaug * 1.1 , coloct < colsep * 1.1 , colnov < coloct * 1.1 , coldec < colnov * 1.1))  ...  or ((colnov > coloct * 1.2 , coldec > colnov * 1.2) , (colfeb < coljan * 1.1 , colmar < colfeb * 1.1 , colapr < colmar * 1.1 , colmay < colapr * 1.1 , coljun < colmay * 1.1 , coljul < coljun * 1.1 , colaug < coljul * 1.1 , colsep < colaug * 1.1 , coloct < colsep * 1.1)) 

in total there 55 lines of or statements check every possible combination of this. if went query similar (e.g. return row id #'s 2 pairs greater 50% , 4 pairs under 10%), involves writing long query scratch checking every other possible combination.

so wondering how re-write in shorter version more re-useable similar queries?

so, alternate answer @pieter's answer , illustrate how simpler data structure may make task easier, suggest following:

create view tbleasy ( select pkid, 1 colmonth, coljan colvalue tblmonthdata union select pkid, 2 colmonth, colfeb colvalue tblmonthdata union select pkid, 3 colmonth, colmar colvalue tblmonthdata union select pkid, 4 colmonth, colapr colvalue tblmonthdata union select pkid, 5 colmonth, colmay colvalue tblmonthdata union select pkid, 6 colmonth, coljun colvalue tblmonthdata union select pkid, 7 colmonth, coljul colvalue tblmonthdata union select pkid, 8 colmonth, colaug colvalue tblmonthdata union select pkid, 9 colmonth, colsep colvalue tblmonthdata union select pkid, 10 colmonth, coloct colvalue tblmonthdata union select pkid, 11 colmonth, colnov colvalue tblmonthdata union select pkid, 12 colmonth, coldec colvalue tblmonthdata ); 

this makes view how have structured table initially. easy create pairs comparing value on colmonth on colmonth + 1.

i made fiddle illustrate how comparing done in view, , query if obvious.

http://sqlfiddle.com/#!3/600f6/4

note performance not great due initial table structure.


update since being accepted answer, embed details sqlfiddle.

extra view pre-calculate difference between consecutive months:

create view tblpairs (   select t1.pkid , t1.colmonth colstart, (t2.colvalue * 100 / t1.colvalue) colpercentage   tbleasy t1   inner join tbleasy t2    on t1.pkid = t2.pkid , t1.colmonth = t2.colmonth - 1); 

query find 2 months have on 20% increase , other 9 have less 10%:

select distinct pkid tblpairs t1 2 = (     select count(*)     tblpairs t2     t2.pkid = t1.pkid     , colpercentage >= 120) , 9 = (     select count(*)     tblpairs t2     t2.pkid = t1.pkid     , colpercentage <= 110) ; 

Comments

Popular posts from this blog

javascript - Jquery show_hide, what to add in order to make the page scroll to the bottom of the hidden field once button is clicked -

javascript - Highcharts multi-color line -

javascript - Enter key does not work in search box -