tsql - Check for equal amounts of negative numbers as positive numbers -


i have table 2 columns: intgroupid, decamount

i want have query can return intgroupid result if every positive(+) decamount, there equal , opposite negative(-) decamount.

so table of (id=1,amount=1.0),(1,2.0),(1,-1.0),(1,-2.0) return intgroupid of 1, because each positive number there exists negative number match.

what know far there must equal number of decamounts (so enforce count(*) % 2 = 0) , sum of rows must = 0.0. however, cases logic are:

id | amount

  • 1 | 1.0
  • 1 | -1.0
  • 1 | 2.0
  • 1 | -2.0
  • 1 | 3.0
  • 1 | 2.0
  • 1 | -4.0
  • 1 | -1.0

this has sum of 0.0 , has number of rows, there not 1-for-1 relationship of positives negatives. need query can tell me if there negative amount each positive amount, without reusing of rows.

i tried counting distinct absolute values of numbers , enforcing less count of rows, it's not catching everything.

the code have far:

    declare @tbltest table(     intgroupid int     ,decamount decimal(19,2) );  insert @tbltest (intgroupid ,decamount) values (1,-1.0),(1,1.0),(1,2.0),(1,-2.0),(1,3.0),(1,2.0),(1,-4.0),(1,-1.0);  declare @intabscount int = 0     ,@intfullcount int = 0;  select @intfullcount = count(*) @tbltest;  select @intabscount = count(*) ( select distinct abs(decamount) abscount @tbltest group abs(decamount) ) abscount  select t1.intgroupid @tbltest t1      /* make sure number of rows */     inner join     (select count(*) intcount @tbltest      )     t2 on t2.intcount % 2 = 0      /* make sure sum = 0.0 */     inner join     (select sum(decamount) decsum @tbltest)     t3 on decsum = 0.0  /* make sure count of absolute values < count of values */      @intabscount < @intfullcount group t1.intgroupid 

i think there better way check table, possibly finding pairs , removing them table , seeing if there's left in table once there no more positive/negative matches, i'd rather not have use recursion/cursors.

boy, found simpler way previous answers. hope crazy edits saved posterity.

  • this works grouping numbers id absolute value (1, -1 grouped 1).
  • the sum of group determines if there equal number of pairs. if 0 equal, other value sum means there imbalance.
  • the detection of evenness count aggregate necessary detect number of zeros. assumed 0's exist , should occur number of times. remove if isn't concern, 0 pass first test.
  • i rewrote query bunch of different ways best execution plan. final result below has 1 big heap sort unavoidable given lack of index.

query

with tt (     select intgroupid,          case when sum(decamount) > 0 or count(*) % 2 = 1 1 else 0 end unequal     @tbltest      group intgroupid, abs(decamount) ) select tt.intgroupid,      case when sum(unequal) != 0 'not equal' else 'equals' end [pair] tt group intgroupid; 

tested values

(1,-1.0),(1,1.0),(1,2),(1,-2), -- should work (2,-1.0),(2,1.0),(2,2),(2,2), -- fail, 2 positive twos (3,1.0),(3,1.0),(3,-1.0), -- fail 2 1's , 1 -1 (4,1),(4,2),(4,-.5),(4,-2.5), -- fail: adds same sum, different values (5,1),(5,-1),(5,0),(5,0), -- work, test zeros (6,1),(6,-1),(6,0), -- fail, test zeros (7,1),(7,-1),(7,-1),(7,1),(7,1) -- fail, 3 x 1 

results

a   pairs _   _____ 1   equal 2   not equal 3   not equal 4   not equal 5   equal 6   not equal 7   not equal 

Comments

Popular posts from this blog

php - get table cell data from and place a copy in another table -

javascript - Mootools wait with Fx.Morph start -

php - Navigate throught databse rows -