ascending or descending order according to boolean column

怎甘沉沦 提交于 2019-12-24 08:48:15

问题


This is the table structure in PostgreSQL 10.

Even though "date" is an int, it represents a yyyy mm dd date. I am trying to write a SELECT that orders by date and when it is BC=true it is desc, so dates will be in the right order -500 01 02 then -500 01 03 (yyyy mm dd)
and when is is BC=false it is asc, so dates will be in the right order again 1500 01 02, then 150 01 03 (yyyy mm dd)

I came up with this SELECT * FROM test ORDER BY bc=true desc, bc=false asc; that does great on BC dates, but it flips the AD dates (15000103 then 15000102, that is wrong).

I know there is the date type available, but I want this to work as a hack for exact BC dates.

How can I change my SELECT to properly order the dates according to the BC boolean column?

Thanks


回答1:


I don't think bc=true desc, bc=false asc is working good. I'll check again when I have my computer and update my answer later.

Maybe my solutions is just a trick or a cheat. This is not a legal way. You can try this.

SELECT * FROM test 
ORDER BY bc DESC, CASE WHEN bc THEN date*(-1) ELSE date END ASC;

Or

SELECT * FROM test 
ORDER BY bc DESC, CASE WHEN bc THEN abs(date) ELSE date END ASC;

Hopefully my answer will satisfy you.




回答2:


I would go with absolute value:

t=# with c(d) as (values(-51),(50))
select * from c order by abs(d);
  d
-----
  50
 -51
(2 rows)



回答3:


I believe a simple union could solve it too.

I tested it on Fiddle: http://sqlfiddle.com/#!9/96ed2/1/0

It seems to work:

( SELECT * FROM mytable 
WHERE bc=true 
ORDER BY date DESC) 

UNION ALL 
( SELECT * FROM mytable WHERE bc=false ORDER BY date)
ORDER BY bc DESC, date

The data set I used:

CREATE TABLE mytable (
  id serial PRIMARY KEY,  
  name VARCHAR (50),
  date INTEGER,
  bc BOOLEAN
);

INSERT INTO mytable (id, name, date, bc) VALUES (1,'one',-6000102, true);
INSERT INTO mytable (id, name, date, bc) VALUES (2,'two',-3000202, true);
INSERT INTO mytable (id, name, date, bc) VALUES (3,'three',-5000103, true);
INSERT INTO mytable (id, name, date, bc) VALUES (4,'four',19000109, false);
INSERT INTO mytable (id, name, date, bc) VALUES (5,'five',15000105, false);

You should know if UNION ALL or UNION is the better choice. ( https://www.postgresql.org/docs/8.3/static/queries-union.html )




回答4:


After testing around and trying different syntax combination, I came up with this, based on this

select * from test
 order by
 case when bc = true then bc end asc ,
 case when bc = true then date end desc,
 case when bc = false then date end asc,
 case when bc = false then bc end desc;

That successfully outputs

-5000102
-5000103
-5000103
5000102
5000103
5000301
5000302
15000102
15000103

So, dates in the yyyy-mm-dd format, from BC to AD, from older to new.



来源:https://stackoverflow.com/questions/48478216/ascending-or-descending-order-according-to-boolean-column

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!