Orderby in SQL Server to Put Positive Values Before Negative Values

OrderBy in SQL Server to put positive values before negative values

Select * from Table
order by
Case when sortcolumn<0 then 1 else 0 end
,sortcolumn

ORDER BY separately positive & negative numbers in MySQL statement

Can use SIGN to sort the positive numbers to the top, then take the absolute value with ABS to get the desired ASC/DESC.

SELECT * FROM theTable
ORDER BY SIGN(col) DESC, ABS(col)

EDIT

As Nahuel pointed out, the above will sort 0's to the middle between positive and negative. To instead group them with the positives, you can use a CASE instead (or, if your column is only integers, the slightly magical SIGN(col + 1))

SELECT * FROM theTable
ORDER BY
CASE WHEN col >= 0 THEN 1 ELSE 2 END,
ABS(col)

How to Order Positive and Negative Integers One after the other

Use the absolute value function when selecting your data.

SELECT my_integer
FROM my_table
ORDER BY ABS(my_integer)

This will order your data by integer magnitude.

How to Sort Amount Number Negative and Positive Number In SQL server

  select * from @t t 
order by expensetype,
case when amount > 0 then 1 else 2 end

result

Entity      ExpenseTypeCode ExpenseType Amount
----------- --------------- ----------- -----------
15 47 airline 556
14 46 Dinner 23
13 45 drink 55
11 43 Hotel 5
16 48 Hotel -5
12 44 travel 23

If you are looking for matching pairs then something like this might be what you want

declare @t table(Entity int, ExpenseTypeCode int, ExpenseType varchar(10),  Amount int)
insert into @t values
( 11, 043, 'Hotel' , 6),
( 8, 043, 'Hotel' , 5),
( 9, 043, 'Hotel' , 5),
( 10, 043, 'Hotel' , 5),
( 12, 044, 'travel' , 23),
( 13, 045, 'drink' , 55),
( 14, 046, 'Dinner' , 23),
( 15, 047, 'airline' , 556),
( 16, 048, 'Hotel' , -5),
( 17, 048, 'Hotel' , -5),
( 18, 043, 'Hotel' , -6),
( 19, 043, 'Hotel' , -6)

select t.*,row_number() over(partition by t.ExpenseType, t.amount order by t.entity) rn,t.amount as absamount
from @t t
where t.amount > 0
union all
select t.*,row_number() over(partition by t.ExpenseTypeCode, t.amount order by t.entity) rn, abs(t.amount)
from @t t
where t.amount < 0
order by t.expensetype,absamount,rn,t.amount desc

result

Entity      ExpenseTypeCode ExpenseType Amount      rn                   absamount
----------- --------------- ----------- ----------- -------------------- -----------
15 47 airline 556 1 556
14 46 Dinner 23 1 23
13 45 drink 55 1 55
8 43 Hotel 5 1 5
16 48 Hotel -5 1 5
9 43 Hotel 5 2 5
17 48 Hotel -5 2 5
10 43 Hotel 5 3 5
11 43 Hotel 6 1 6
18 43 Hotel -6 1 6
19 43 Hotel -6 2 6
12 44 travel 23 1 23

or possibly a full join

select  s.*,t.* from
(
select t.*,row_number() over(partition by t.ExpenseType, t.amount order by t.entity) rn
from @t t
where t.amount > 0
) s
full join
(
select t.*,row_number() over(partition by t.ExpenseTypeCode, t.amount order by t.entity) rn
from @t t
where t.amount < 0
) t on t.expensetype = s.expensetype and t.rn = s.rn and abs(t.amount) = s.amount
order by s.expensetype

Entity ExpenseTypeCode ExpenseType Amount rn Entity ExpenseTypeCode ExpenseType Amount rn
----------- --------------- ----------- ----------- -------------------- ----------- --------------- ----------- ----------- --------------------
NULL NULL NULL NULL NULL 19 43 Hotel -6 2
15 47 airline 556 1 NULL NULL NULL NULL NULL
14 46 Dinner 23 1 NULL NULL NULL NULL NULL
13 45 drink 55 1 NULL NULL NULL NULL NULL
11 43 Hotel 6 1 18 43 Hotel -6 1
10 43 Hotel 5 3 NULL NULL NULL NULL NULL
8 43 Hotel 5 1 16 48 Hotel -5 1
9 43 Hotel 5 2 17 48 Hotel -5 2
12 44 travel 23 1 NULL NULL NULL NULL NULL

Row of the first positive number preceding a negative number in Postgres?

You can use a combination of window functions to do this. First, use count as a window function, incrementing the count only when column2>0. This will segregate your rows into the groups you'll need to pick out the positive value. We can then use first_value to grab the first row from the partition, which will be the positive value:

create table test (column1 int, column2 numeric, column3 date);
insert into test VALUES (30, 2.5, '2019-01-01'), (31, 1.5, '2019-01-02'), (28, -0.8, '2019-01-03'), (29, 1.0, '2019-01-04'), (30, 1.2, '2019-01-05'), (38, -2.1, '2019-01-06'), (37, -2.2, '2019-01-07');

SELECT column1,
column2,
first_value(column2) OVER (PARTITION BY col2_group ORDER BY column3)
FROM (
select column1,
column2,
-- Create groups of rows
count(column2) FILTER (WHERE column2>0) OVER(ORDER BY column3) as col2_group,
column3
FROM test) as sub
ORDER BY column3
;
column1 | column2 | first_value
---------+---------+-------------
30 | 2.5 | 2.5
31 | 1.5 | 1.5
28 | -0.8 | 1.5
29 | 1.0 | 1.0
30 | 1.2 | 1.2
38 | -2.1 | 1.2
37 | -2.2 | 1.2
(7 rows)

In the future, it would be very helpful if you would add the data and the expected output, separately, as text, not an image.



Related Topics



Leave a reply



Submit