| Author |
Topic |
|
ninel
Posting Yak Master
141 Posts |
Posted - 2006-05-02 : 11:23:07
|
I have 2 fields in a table: an Id and an amount field.CREATE TABLE AMOUNT(AmountId [int] IDENTITY (1, 1) NOT NULL ,Amount numeric(10,2) NULL)INSERT #AMOUNT (Amount)VALUES(125.23)INSERT #AMOUNT (Amount)VALUES(-125.23)INSERT #AMOUNT (Amount)VALUES(125.23)INSERT #AMOUNT (Amount)VALUES(33.45)INSERT #AMOUNT (Amount)VALUES(-33.45)INSERT #AMOUNT (Amount)VALUES(20.20) So the data in the table will look like this:Id AmountId1 125.232 -125.233 125.234 33.455 -33.456 20.20I need a query that returns records 3 and 6 becuase they don't have matching negative values.I used the following code:SELECT distinct a.*, b.Amount, b.AmountidFROM AMOUNT aLEFT OUTER JOIN AMOUNT b ON a.amount = (b.amount *-1)WHERE b.AmountId is NULL This returns the 20.20, but doesn't return the 2nd 123.25.Can anyone help me with this?Thanks,Ninel |
|
|
nr
SQLTeam MVY
12543 Posts |
Posted - 2006-05-02 : 11:27:12
|
| SELECT distinct a.*, b.Amount, b.AmountidFROM AMOUNT aFULL OUTER JOIN AMOUNT b ON a.amount = (b.amount *-1)WHERE b.AmountId is NULLor a.AmountId is NULL==========================================Cursors are useful if you don't know sql.DTS can be used in a similar way.Beer is not cold and it isn't fizzy. |
 |
|
|
druer
Constraint Violating Yak Guru
314 Posts |
Posted - 2006-05-02 : 11:28:22
|
| Is the definition of the "problem" that the negative value will come immediately after the positive value? As I see just the input how do I know that record 2 -125.23 doesn't match with record 3, so I should get Row 1 and row 6? Will it always be immediately after, or could record 18 contain a -125.23 that would map to record 3?Hope it helps,DaltonBlessings aren't so much a matter of "if they come" but "are you noticing them." |
 |
|
|
druer
Constraint Violating Yak Guru
314 Posts |
Posted - 2006-05-02 : 11:31:41
|
| nr, that returns basically the same thing and still excludes the 125.23 which comes a second time. The Distinct is simply finding unique values and not taking the "counts" for them into account.Hope it helps,DaltonBlessings aren't so much a matter of "if they come" but "are you noticing them." |
 |
|
|
ninel
Posting Yak Master
141 Posts |
Posted - 2006-05-02 : 11:35:32
|
| nr,You're query is returning the following:AmountId Amount Amount AmountIdNULL NULL 20.20 55 20.20 NULL NULLI need to see:5 20.206 123.25 |
 |
|
|
nr
SQLTeam MVY
12543 Posts |
Posted - 2006-05-02 : 11:35:58
|
| You probably also should match on the count of the values in case there are 2 positives with one negative.The usual way to do this is to assign a match id to the rows then output any that are left over but you could.select * from amount where abs(amount) in (SELECT distinct coalesce(a.amount, b.amount)FROM (select amount, num = count(*) AMOUNT from amount where amount < 0 group by amount) aFULL OUTER JOIN (select amount * -1, num = count(*) AMOUNT from amount where amount < 0 group by amount) bON a.amount = b.amountand a.num = b.numWHERE b.Amount is NULLor a.Amount is NULL)==========================================Cursors are useful if you don't know sql.DTS can be used in a similar way.Beer is not cold and it isn't fizzy. |
 |
|
|
ninel
Posting Yak Master
141 Posts |
Posted - 2006-05-02 : 11:36:33
|
| I'm sorry... I meantId Amount3 125.236 20.20 |
 |
|
|
nr
SQLTeam MVY
12543 Posts |
Posted - 2006-05-02 : 11:38:14
|
quote: Originally posted by ninel nr,You're query is returning the following:AmountId Amount Amount AmountIdNULL NULL 20.20 55 20.20 NULL NULLI need to see:5 20.206 123.25
SELECT Amountid = coalesce(a.Amountid, b.Amountid),Amount = coalesce(a.Amount, b.Amount)FROM AMOUNT aFULL OUTER JOIN AMOUNT bON a.amount = (b.amount *-1)WHERE b.AmountId is NULLor a.AmountId is NULL==========================================Cursors are useful if you don't know sql.DTS can be used in a similar way.Beer is not cold and it isn't fizzy. |
 |
|
|
ninel
Posting Yak Master
141 Posts |
Posted - 2006-05-02 : 11:39:36
|
| nr, num = count(*) Are you placing the count into a varaible? |
 |
|
|
nr
SQLTeam MVY
12543 Posts |
Posted - 2006-05-02 : 11:41:53
|
| Nope, it's just getting the count of the rows with that amount so that can be matched too.I made a few mistakes in the query which I've corrected (still haven't tried it though).==========================================Cursors are useful if you don't know sql.DTS can be used in a similar way.Beer is not cold and it isn't fizzy. |
 |
|
|
ninel
Posting Yak Master
141 Posts |
Posted - 2006-05-02 : 11:43:50
|
| Its still giving me 2 records of 20.20. |
 |
|
|
druer
Constraint Violating Yak Guru
314 Posts |
Posted - 2006-05-02 : 11:53:10
|
| The following will show you the two values that don't have matches, but not the ID's of the values since you still never answered my question about the basic definition and there is nothing inherent in the data to indicate that the 1 value of 125.23 matches either or the other ID value.[CODE]declare @pos table (value numeric(10,2), cnt int)declare @neg table (value numeric(10,2), cnt int)insert into @pos select amount, count(*) from #amount where amount > 0 group by amountinsert into @negselect amount, count(*) from #amount where amount < 0 group by amountselect p.valuefrom @pos p left join @neg n on p.value = n.value * -1.0where (n.value is not null and p.cnt > n.cnt)or (n.value is null)[/CODE]Hope it helps,DaltonBlessings aren't so much a matter of "if they come" but "are you noticing them." |
 |
|
|
ninel
Posting Yak Master
141 Posts |
Posted - 2006-05-02 : 12:02:48
|
| Thanks. That did work.Ans the negative value will not always immediatley follow the positive value.Is there any way to do this within one query? |
 |
|
|
nr
SQLTeam MVY
12543 Posts |
Posted - 2006-05-02 : 12:36:11
|
| An enhancement of my previous query (and tested).select * from #amount where amountID in (SELECT distinct coalesce(a.amountID, b.amountID)FROM (select a.amountID, a.amount, num = (select count(*) from #amount a2 where a2.amount = a.amount and a2.amountId <= a.AmountID) from #amount a where amount < 0 group by amountId, amount) aFULL OUTER JOIN (select a.amountID, amount = a.amount * -1, num = (select count(*) from #amount a2 where a2.amount = a.amount and a2.amountId <= a.AmountID) from #amount a where amount > 0 group by amountId, amount) bON a.amount = b.amountand a.num = b.numWHERE b.amountID is NULLor a.amountID is NULL)==========================================Cursors are useful if you don't know sql.DTS can be used in a similar way.Beer is not cold and it isn't fizzy. |
 |
|
|
ninel
Posting Yak Master
141 Posts |
Posted - 2006-05-02 : 12:40:54
|
| Thank you so much.I really appreciate all your help. |
 |
|
|
|