We have a table of users with column membership_end which is, as the name say - the date when users membership end. Now some users never purchase membership so that field is empty. For some users, that field is in the past (membership expired). What I need is to sort the active members first (ordered by the membership_end date desc), then the rest of the users in some independent sorting order. Basically we need to show active members on top.
SELECT * FROM accounts where membership_end>=now()
order by membership_end desc
union
???
Thanks in advance
Ok, to clear things up a bit.
SELECT * FROM accounts where membership_end>=now()
order by membership_end desc
gives us 12 active members and this is fine. we then have this:
SELECT * FROM accounts where membership_end<now()
order by id desc
we simply need to combine these two in one query. that's all.
EDIT: Actually i figured it out. It's quite simple.
SELECT id, membership_end FROM accounts ORDER BY membership_end >= NOW( ) DESC , id DESC
no unions. no complicated queries :-)
You can sort null values to be first, so you could avoid unions :
SELECT membership_end FROM accounts
where membership_end>=now() or membership_end is null
ORDER BY [membership_end] IS NULL DESC, [membership_end] DESC
If you do not want duplicates I would recommend to do this. I don't know what condition you want to use to filter members with null membership_end filed but if all I would do something like that:
SELECT membership_end FROM accounts where membership_end>=now() or membership_end is null order by membership_end desc
Descending ordering should put members with null membership_end in the end of list so you may want to add additional ordering.
Try something like this:
SELECT membership_end FROM table1 where membership_end>=now()
Union all
SELECT membership_end FROM table2 where membership_end>=now()
this will combine table1 and table2
The important bit is 1 field for table1 and 1 field for table2 only. It must be the same.
Two tricks here 1) associate ids with dates by creating a combined date + id field, historic and nulls have been given a seed date in the future to avoid overlaps with future dated members (you may wish to push this out) 2) allocate a srce number to the unioned statements.
/*
create table m (id int, enddte date);
truncate table m;
insert into m values
(1,null),(2,'2016-10-01'),(3,'2016-11-10'),(4,'2016-02-01'),(5,'2016-03-01'),(6,null);
*/
select * from
(
select 1 as srce,m.id,m.enddte ,
year(m.enddte) * 10000 + month(m.enddte) * 100 + m.id as uniqueid
from m
where m.enddte >= now()
) s
union
(
select 2,id,enddte,
year(cast('2050-01-01' as date)) * 10000 + month(cast('2050-01-01' as date)) * 100 + id
from m
where m.enddte < now() or m.enddte is null
)
order by srce,uniqueid desc
or you could do this without a union
select * from
(
select case
when enddte >= now() then 1
else 2
end as srce,
id, enddte,
case
when enddte >= now() then year(m.enddte) * 10000 + month(m.enddte) * 100 + m.id
else year(cast('2050-01-01' as date)) * 10000 + month(cast('2050-01-01' as date)) * 100 + id
end as uniqueid
from m
) s order by srce,uniqueid desc
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.