Reputation: 986
This an example table and I want to get all negative numbers and minimum positive number (0 included) for per id
declare @tbl table(id INT, value decimal, someData varchar(10))
insert into @tbl
values(1,-3,123),(1,-2,234),(1,-1,345),(1,3,456),(1,4,567),(2,-4,678),(2,-2,789),(2,1,890),(2,2,135),(3,-5,246),(3,10,357)
select * from @tbl where value < 0 union
select id, min(value),someData from @tbl WHERE value > 0 group by id,somedata
I am trying to find a solution by separating minuses and pluses. but because of someData I cannot group by them as I need.
desired result is:
1 -3 123
1 -2 234
1 -1 345
1 3 456
2 -4 678
2 -2 789
2 1 890
3 -5 246
3 10 357
Also its a long working query so I dont want to make double select. Is it possible to make it in one select?
Upvotes: 0
Views: 878
Reputation: 93724
using Window function
u can get minimum values. and use UNION
to combine the results. TRY THIS..
;WITH CTE
AS (SELECT Row_number() OVER (PARTITION BY ID ORDER BY value) RN, *
FROM @tbl
WHERE value > 0)
SELECT *
FROM @tbl
WHERE value < 0
UNION ALL
SELECT ID,value,someData
FROM CTE
WHERE RN = 1
Upvotes: 0
Reputation: 239694
This should work:
;With separated as (
select *,ROW_NUMBER() OVER (PARTITION BY SIGN(value),id ORDER BY value) as rn
from @tbl
)
select * from separated where SIGN(value) < 0 or rn=1
You haven't said what should happen if value
is 0 so the above may or may not be correct if your data contains some.
SIGN
is a little-used but occasionally useful function in SQL Server, returning -1, 0 or +1 and allowing us to easily partition the groups of numbers into 3 groups.
Upvotes: 1
Reputation: 425043
Attack it as a single select with an OR where clause, using a subquery to get the minimum positive number:
select * from @tbl
where value < 0
or value = (
select min(value)
from @tbl
where value > 0)
Upvotes: 0
Reputation: 109015
Using a union to combine the conditions is likely easiest. But to select the row with the minimum positive value requires an sub-query, and the assumption that ID is a unique identifier:
select id,value,somdata from @tbl where value < 0
union
select id,value,somdata from @tbl
where value = (select min(value) from @tbl where value > 0)
(That won't include rows with a zero value, but the question doesn't say which side they should fall.)
Upvotes: 0