i'm trying to order a returned set, but i'm having a hard time getting it to order properly.
i'm selecting fields, and each field has a date_updated and a date_added.
when the field is added, the date_updated is null, until there is an update, which it then assigns the current date.
i need to order my list by having the most recent entries be on the BOTTOM, and oldest on the top. so if a item is added, it should go directly to the bottom. is there a way to join all the date fields together, and then just sort by oldest to newest, disregarding update or added?
this may sound kind of confusing, but i've already tried numerous combinations of ORDER BY date_added DESC, date_updated ASC, and things like that, but it's not doing what I need it to do. i get the top portion ordered by date_added and then under that is a separate ordering for date_updated...
any input would be really helpful here...
try
order by coalesce(date_updated, date_added)
COALESCE DOC
You can try a CASE statement
SELECT
firstname,
lastname,
date_added,
date_updated,
CASE date_updated IS NULL
THEN date_added
ELSE date_updated
END CASE AS order_date
FROM mytable
ORDER BY order_date DESC
What this does is it checks if date_updated is null and then puts in the new column the value of date_added. If not, it puts the date_updated. The new column is called order_date and is used for sorting.
You can also add the CASE statement in the ORDER BY clause but that might slow your query down since it has to do the concatenation on the index vs. when constructing the data. Although not conclusive, I have found a slight performance gain if the CASE is used in the SELECT vs. the ORDER BY.
Use CASE in Order By Clause.
ORDER BY CASE WHEN date_updated IS NULL
THEN 0
ELSE 1
END DESC, date_added DESC
Order by IsNull(DateUpdated,DateAdded)
would be one way
Related
I have a table with 4 different date columns (date_created, date_saved, date_published, date_deleted), and I'm trying to do a "most recent updates" query, effectively taking any of those 4 dates into consideration and sorting by the most recent dates desc. Normally you'd do:
date_created DESC, date_saved DESC, date_published DESC, date_deleted DESC
But I don't want it to give more importance to date_created than date_deleted. All the date fields are an "update" so they should all be treated equally in the sorting.
I'd rather not select all the results in the whole database and then use PHP to sort and limit for resources sake, so, is there a way sort DESC on all of those 4 fields, while treating them all as equal importance?
simply do:
ORDER BY GREATEST(date_created, date_saved, date_published, date_deleted)
My brain is failing me in this. I'm sure this is easily found by searching, but I'm having a hell of a time wording it to find any relevant results.
I'm using Laravel, so if there's an Eloquent solution, that would be preferred, but a RAW query would be fine as well.
I have a table, called threads, which has the two columns status and of course updated_at. I would like to sort by updated_at DESC, but have any rows with a status of a specified value returned on top, but also that group sorted by updated_at.
I hope that makes sense.
Here's what I believe you need.
ORDER BY status=17 DESC, updated_at DESC
Edit. This ORDER BY expression doesn't have any effect on the rows selected, only on their ordering. It works because the expression status=17, as a Boolean value, has either the value 1 or 0. Ordering it DESC puts the true ones first and the false ones second. Then the updated_at DESC puts the rows in descending order by date.
I'm guessing about 17. Put your desired status there instead.
This
it sounds like you want
select status, updated_at from threads order by status, updated_at desc
Below is a preview of what I have so far:
MySQL Table:
What I want to do is be able to sort this in a certain way. I would like for all rows that are "FREE" to be at the very top, so where special_price is equal to 0.00.
I also would like all rows with a special to be after that, and then all rows with just a normal price would be after that. Is there any way to do that without specifying a sort_id so the user wouldn't have to change the order themselves?
So in the above example, the last field "Testing" would be moved up one, and "Replace Air Filter" would be last.
Right now in my query there is no ORDER BY, so it is ordering by the id.
Any help is appreciated. Thanks!
ORDER BY COALESCE(special_price,99999) ASC, price ASC
should do the trick.
Explaination
COALESCE is a function that takes the first non-null value, so anywhere you have a null special price, it will default to 99999 (just some arbitrary high number to get it at the end of the ordering). From there we order on price, so any ties, as well as the end of the list, will be in ascending order by price.
You can combine two selects with UNION
SELECT * FROM `table` WHERE `special_price` IS NOT NULL ORDER BY `special_price` ASC,`price` ASC;
UNION ALL
SELECT * FROM `table` WHERE `special_price` IS NULL ORDER BY `price` ASC;
I don't know, how this behaves from the performance point of view, but as far as I know this is just like two simple queries, with the small overhead from UNION.
Minor update: Because both queries cannot return the same records the default behaviour UNION DISTINCT is not required and I hope, that UNION ALL is just a little bit more performant.
Using a function return value to sort the results can be very slow if you are sorting a large number of rows because MySQL can't use an index to sort these values. So how to get around this?
If an item MUST be on special to be free (which seems to be the case from the table layout image you provided) you could try:
SELECT *, special_price IS NULL AS not_special
FROM tablename
ORDER BY not_special ASC, special_price ASC, price ASC;
This adds an extra column to the results that equals 0 if the item is on special, 1 if not. We then put all the "special" items at the top of the sort and sort by ascending special price and price.
This will allow you to avoid the overhead of UNION, still use an index for the sort operation and avoid very slow queries when sorting a large number of rows with a function return value ... but only if an item must be on special to be free.
try
SELECT * FROM table_name ORDER BY CASE special_price
WHEN '0.00' THEN 1
WHEN null THEN 3
ELSE 2
END
I have followings 3 values that could be in a row in database - ON, OFF, SOLD (column sort_it). When I set the sort clausule on ORDER BY sort_it ASC, so I will get the items with a value in the sort_in column OF, then ON and SOLD.
But I need the sequence ON, OFF, SOLD.
Exist any way to do it somehow? I mean... edit a way saving data into database will be demanding, so I would do this in the last moment.
Yes you can use custom data sortings like this:
SELECT * FROM table ORDER BY FIELD(`sort_it`,'ON','OFF','SOLD'),`sort_it`
You can use a CASE statement to generate your custom ordering sequence from the underlying values, something like this:
ORDER BY
CASE sort_it
WHEN 'ON' then 1
WHEN 'OFF' then 2
WHEN 'SOLD' then 3
END
Sample Demo: http://sqlize.com/MGz6lLb0Qk
Using Strings is generally a bad idea. it would be better to use a numeric type. Then you can say ON=1, OFF=2 and SOLD=3 and then sort.
SELECT t.*, IF(sort_it='ON',1,IF(sort_it='OFF',2,3)) as new_sort FROM Table AS t ORDER by new_sort ASC
Another solution from comments on MySql manual:
http://dev.mysql.com/doc/refman/5.0/en/sorting-rows.html
select * from tablename order by priority='High' DESC, priority='Medium' DESC, priority='Low" DESC;
Alright, I'm trying to figure out why I can't understand how to do this well...
I have two tables:
invoices:
id
userID
amount
date
payments:
id
userID
amount
date
So, the goal here is to join both tables, where the userID matches whatever I want it to be - and then return everything ordered by date (most recent at the top). However, because there is a date field in each of the tables, I'm not sure how MySQL will handle things... will is sort by both dates automatically? Here's what I was thinking...
"SELECT DISTINCT *
FROM invoices,payments
WHERE {$userID} = invoice.userID
OR {$userID} = payments.userID
ORDER BY date DESC";
But, it's starting to become clear to me that maybe this isn't even the right use of a join command... maybe I need to just get all data on each table alone, then try to sort it somehow with PHP? If that's the better method, what's a good way to do this type of DATE sort while keeping all row data in tact?
I should add, the TIME inside the unix timestamp (that's how "date" is stored) is NOT negligible - it should sort by the date and time.
Thanks all...
If the columns of both tables are the same, you can use a UNION
SELECT X.*
FROM ( SELECT `id`,
`userID`,
'INVOICE' AS PTYPE
`amount`,
`date`
FROM `invoices`
WHERE {$userID} = userID
UNION
SELECT `id`,
`userID`,
'PAYMENT' AS PTYPE
`amount`,
`date`
FROM `payments`
WHERE {$userID} = userID
) X
ORDER BY X.`date`
EDIT
Read the relevant section of the MySQL manual on UNIONS. There are other ways of phrasing this, but this is my preferred style - it should be clear to anybody reading that the ORDER BY clause applies to the result of both sides of the UNION. A carelessly written UNION - even with an ORDER BY - may still leave the final resultset in indeterminate order.
The purpose of the PTYPE is that this query returns an extra column called PTYPE, that indicates whether each individual row is an INVOICE or a PAYMENT... ie. which of the two tables it comes from. It's not mandatory, but can often be useful within a union
Because you have two identical fields named date, MySQL will not know which one you're trying to order by.
"SELECT DISTINCT *
FROM invoices,payments
WHERE {$userID} = invoice.userID
OR {$userID} = payments.userID
ORDER BY invoices.date, payments.date DESC";
This would sort on the invoice date, then the payment date - if that's what you are trying to find out
If your data tipe is Date, Timestamp, or anything related, the SGBD will order it properly. If that was what you've asked.
But if the datatype is String, even when dates is store, it will not sort the way you want.