I have a table with a column priority_n. Pretend there are 5 items in that table. Two with nil as priority_n, and the other three have 1, 2, 3.
I'd like to do a where(priority_n: nil).order(published_at: :desc) combined with where.not(priority_n: nil).order(priority_n: :asc). I want the nil ones at the beginning of the active record relations, and then the prioritized ones after them. Is there a way to do this?
If I could figure out how to do this in SQL then I could do it in rails.
The following is the order by clause in standard SQL:
order by (case when priority_n is null then 0 else 1 end),
priority_n asc
Case statements will not make efficient use of indexes.
ORDER BY priority_N IS NULL DESC, priorit_n ASC
In PostgreSQL, sorting nulls first / last is dead simple with the (standard SQL!) NULLS FIRST | LAST:
ORDER BY priority_n NULLS FIRST, published_at
The second ORDER BY item, because it seems you want to order rows with the same priority_n according to published_at.
PostgreSQL sort by datetime asc, null first?
ORDER BY DATE showing NULLS first then most recent dates
MySQL does not implement NULLS FIRST | LAST. Substitute with:
ORDER BY priority_n IS NOT NULL, priority_n, published_at
Would work in Postgres, too.
priority_n IS NOT NULL is a boolean expression that evaluates to FALSE (0) or TRUE (1). 0 sorts before 1 (and both before NULL, but not relevant here.), so rows with priority_n IS NULL come first.
ORDER BY ASC with Nulls at the Bottom
MySQL Order by column = x, column asc?
Related
I have a table in a MySQL database.
One of the columns is entitled Failed and some rows have the value Yes in them.
How do I order my SELECT query so it shows the rows that have no value first and then shows the ones with Yes as the value at the end?
Just use ASC or DESC when ordering on the field(s) you wish to order by. In this case try:
ORDER BY Failed ASC
Use CASE in Order by
Order by case when col <> 'yes' then 2 else 1 end
I am sure it would be an aggregate function because it is going to count a collection of data.
However, how does any COUNT() function operate in MySQL to perform its respective actions?
Not 100% clear what you are looking for, but for selecting a count of null values in a column, I use something like this:
SELECT SUM(CASE WHEN columnname IS NULL THEN 1 ELSE 0 END) FROM tablename;
When the value is NULL, it is assigned the value 1 otherwise 0, then summed over whatever aggregate you need.
The COUNT(*) is an aggregate function. In the SELECT list, the expression COUNT(*) will return a count of rows. Without a GROUP BY clause, all rows will be collapsed into a single row, and the COUNT(*) aggregate will contain a non-negative integer value representing the number of rows that were collapsed... a "count" of the number of rows.
As you seem to be aware, other expressions involving the COUNT() aggregate operate a little differently, with respect to NULL values.
In the SELECT list, an expression COUNT(expr) operates exactly like COUNT(*) except for rows with values of expr that evaluate to NULL are not included in the count.
This all operates according to the specification.
As far as the non-existent COUNTNULL() function, it depends what you want that to achieve. If you wanted to get a count of the rows that had a NULL value for an expression, you could perform a conditional test, and return a non-NULL value, and use the existing COUNT aggregate, for example:
SELECT COUNT(CASE WHEN expr IS NULL THEN 1 ELSE NULL END) AS `COUNTNULL`
FROM ...
I don't remember where I learned this technique, but arguably the most elegant -- or at least minimalistic -- way to invert the logic of COUNT() is with this expression, which admittedly gives a first impression that black magic may somehow be involved... but it's perfectly legitimate:
COUNT(column1 IS NULL OR NULL)
...this correctly counts only the rows where column1 is null, because it is equivalent to the following expression...
COUNT( (column1 IS NULL) OR (NULL) )
It's a boolean expression that can only ever evaluate to 1 ("true," when column1 is null, and this row is thus counted), or NULL (otherwise, so the row will not be counted).
Logically, it's equivalent to the CASE expression offered by #spencer7593.
I am having table "business" as bellow
I want to fetch the record order by type in custom order. So I wrote the query like
SELECT * FROM business
ORDER BY FIELD (type, 'type3', 'type2', 'type10')
but what happen is other types comes up in order and the given order becomes at last. The given order should be at top and then other records. Above query returns the result as bellow.
How to bring the type3, type2 and type10 at top in order.
So that will be:
SELECT
*
FROM
business
ORDER BY
`type` IN ('type3', 'type2', 'type10'),
FIELD (`type`, 'type3', 'type2', 'type10')
Try below:
ORDER BY
CASE `type`
WHEN 'type3' THEN 1
WHEN 'type2' THEN 2
WHEN 'type10' THEN 3
ELSE 4
END
To see the selective data in top of the result set using field function you have to use either ASC or DESC on these set of values. Else the default result will be returned. Yours is an example of it.
You can try with
ORDER BY FIELD (type, 'type3', 'type2', 'type10') DESC
to see the results as
type10
type2
type3
How to bring the type3, type2 and type10 at top in order
Using ASC will result
type3
type2
type10
The input order of data to the function Field is the priority for display when used with ASC or DESC. Else the result would be default.
These fields I do not have given in query
They sure will be in resultset unless you specify a WHERE condition. FIELD function is not an alias to WHERE clause.
Refer to:
Ordering by specific field values with MySQL
MySQL: Sorting Rows
I'm currently doing this via two separate queries from PHP, but would love to optimize and somehow in a single query.
First query..
SELECT `referrer`
FROM `tbl_traffic_log`
WHERE `domain` = 'mysite.com'
AND `referrer` != '$referringDomain'
AND CASE WHEN `clicks_in_unique`=0 THEN 2 ELSE `clicks_out_unique`/`clicks_in_unique` END < 1.4
ORDER BY RAND()
LIMIT 1
..and if mysql_num_rows shows no results, I do a second query to try again and check if there are any results minus the referrer != 'partner1.com' part.
The code is basically trying to find a random trade partner who ISN'T the partner who sent that click, but if there are no matches, as a last resort it's ok to send back, provided it matches the other criteria.
I'm pretty sure there is a way to do this, but just can't find a way after searching (probably because I'm not understanding the problem enough to type in the right thing).
Any other critique of the query is welcome as well.
Thank you :)
I think you can do this like this:
SELECT `referrer`
FROM `tbl_traffic_log`
WHERE `domain` = 'mysite.com'
AND CASE WHEN `clicks_in_unique`=0 THEN 2 ELSE `clicks_out_unique`/`clicks_in_unique` END < 1.4
ORDER BY `referrer` != '$referringDomain' desc, RAND()
LIMIT 1
The idea is to put the condition in the order by. The condition (in MySQL) evaluates to either 0 or 1, so we want where the condition is true first (hence the desc). It then chooses a random row. If there are no rows where the condition is true, then it chooses a random row.
I have a MySQL database and a have a funny question.
I need to order the results of a query by a field which has entries of 1,2,3 or 4, ordered descending but with 4 at the end.
So I wish to have the results in the following order
3's
2's
1's
4's
Is this possible at all?
I know I can do order the result array in php but unfortunately I need to do this in an sql statement.
If the field is an int,
ORDER BY (fieldname = 4) DESC, fieldname DESC
should do the trick.
Here is another cool way
ORDER BY MOD(fieldname,4) DESC,fieldname
If the result is a CHAR(1) then
ORDER BY LOCATE(fieldname,'3214'),fieldname
add this to the order
ORDER BY
CASE field_name WHEN 4 THEN 1
ELSE 2
END
this will return the result of the query order using the value of the field