MySQL order by syntax - mysql

Ive just seen the following syntax : select * from table order by column = "b" desc
I guess that the rows with value "b" will come first but i am not sure.
What does the query mean and how sorting works in this case.
Ive searched on google about it but ... no success.

In SQL, you are not limited by sorting on values of existing columns: you can specify complex expressions inside your order by clause. This query sorts by the value of a boolean expression: the expression will be true for the rows where column = 'b', and false in all other rows. As the result, rows with column = 'b' will come first, because the order by clause specifies descending order, and in SQL, true is represented as 1, and false is 0.

Related

MySQL where condition with only a reference to a column, what does it mean?

Examples:
SELECT *
FROM table t
WHERE t.col1
SELECT *
FROM table t
WHERE t.col1 AND t.col2
Depending the nature of the column these queries behaves differently. In my tests, if the column is of the type integer wont show rows with 0s or nulls for that column, if it string, the query will give no result.
I'd like to understand what these types of where conditions mean. Couldn't find any specification for this in the MySQL manual nor an explanation online.
Thanks.
In your query you are not assigning a valid comparision in the where clause (eg: where t.col1 = 10) .. so the where condtion try to eval a casting for the value in the columns mentioned as boolen
in this case the diffent result is just based on the different casting in boolean of each type
if you firts query based on a integer return always a valid true result so yoi get all the rows in the others with string depending of each string value this can produce no rows ,, partial rows or all rows .. try look at the result for the cast of your column in boolean
SELECT if(t.col1, true, false)
FROM table t
WHERE t.col1
and
SELECT if( t.col1 AND t.col2, true,false)
FROM table t
WHERE t.col1 AND t.col2
Those just aren't proper boolean expressions. Boolean expressions evaluate to either true or false and are of the form where t.col1 = 0 and t.col2 >= 3 for example.
The fact that your statements sometimes return data and sometimes not is due to the fact, that 0 and 1 stands for false and true respectively.
Like you already observed, 0 and NULLs don't return rows because they are treated as false in case of 0 and not comparable in case of NULL. Strings on the other hand are implicitly converted to numbers. If the string starts with a number other than 0, the string is converted to that number in MySQL. If the string starts with anything other than that, it's converted to 0. That's why you don't get results for strings.
I would recommend to not use these "short hand boolean expressions". Always write proper expressions!

mysql WHERE CLAUSE to exclude rows based on two different values in same column

I'm using MySQL Data Compare to compare a local & remote mysql db.
I'm trying to setup a simple WHERE clause that excludes any rows from the comparison that contain the following values:
%mm or %transient%
The WHERE clause i'm using doesn't seem to be working.
'option_name' NOT LIKE '%_transient_%' OR '%mm%'
The full query that's running is:
SELECT 'option_id', 'option_name', 'option_value', 'autoload'
FROM 'wp_options WHERE 'option_name' NOT LIKE '%_transient_%' OR '%mm%'
And the resulting output does not exclude the rows that that have mm or _transient_ in the option_name column.
The caveat here is that I'm limited to only using a WHERE clause & I'm not able to edit the SELECT clause leading up to it (as that's all generated by the software).
There is no form of LIKE for comparing to multiple patterns.
As #vkp mentioned in a comment (I don't know why they don't post an answer), your condition won't do what you intend:
WHERE option_name NOT LIKE '%_transient_%' OR '%mm%'
It's not a syntax error in MySQL, because OR can use any expression as operands. Zero values count as false, nonzero values count as true. So your condition is equivalent to:
WHERE (option_name NOT LIKE '%_transient_%') OR ('%mm%')
Which is logically equivalent to:
WHERE (option_name NOT LIKE '%_transient_%') OR (true)
Which will be true on every row, because a true value OR'd together with any other expression will result in true.
Your condition should be this:
WHERE option_name NOT LIKE '%_transient_%' AND option_name NOT LIKE '%mm%'

How do I find the newest matching record in MySQL when all of my search criteria can be null?

I have a table with the nullable fields that I use as search criteria, and a creation_date for sorting by.
I'm trying to write a query to find the newest record based on those search criteria, but if one of them is missing I'd like to still match it.
So I tried doing fieldname = ? or null for each field and used order by creation_date limit 1, but if I do this then if there were a row where all of the fields were null, it would return that one instead of an older record where they are not all null.
How can I make it prefer results with more matching fields, but not require that every field exists?
Please try something like the following:
SELECT
{field list}
FROM
{your table}
WHERE
IFNULL(field1, #par1) = #par1
AND IFNULL(field2, #par2) = #par2
.....
ORDER BY
creation_date DESC
limit 1
In the above case if i.e. field1 had a NULL value for a particular record, IFNULL function would return the second parameter given, so the real comparison in that case would be #par1 = #par1 which is always-true. Thus in case of NULL-valued field, the part doesn't affect the search results.
I hope it helps some way.

MySQL Unexpected Result from "in (' ' or ' ')"

What I'm Using: The most recent MySQL on Ubuntu 12.
The Set Up: Suppose I have a table "EmployeePayment" with "Name" and "Hours" for each employee. Suppose I already have it populated with values.
The Question: When I use the command
select * from EmployeePayment where Name in ('');
I get the empty set, as I'd expect. But, when I use
select * from EmployeePayment where Name in ('' or '');
I get the entire table returned. Moreover, if I'm picky and put in the command
select Name, SUM(Hours) from EmployeePayment where Name in ('' or '');
then it only returns whatever is the top name from the table. What's happening with this "in" command?
First off, you need to get rid of the or, the proper syntax for the in clause uses commas to separate the possibilities, such as:
sql> select name from people where status in ('intelligent', 'good looking')
pax
1 row returned
What your current variant is doing is applying the or operator to give you a one-element in-list. See here for more detail.
The reason why you're only getting one row for the aggregated query is because you have no group by clause, so you're grouping all rows. Most DBMS' would then complain about having a non-aggregated column that isn't part of the grouping, but MySQL is a bit fancy-free and footloose with the rules in that regard.
It's obviously grouping over the whole table (as it should) but applying some default aggregating function to the name (which it probably shouldn't, but does according to its documentation).
This MySQL extension is covered here but heed the warning: MySQL can choose any of the myriad possible values for these non-aggregated, non-group-by columns, so it's more useful when you know that all the rows in a given group share the same value for the column.
You're effectively doing this:
select * from EmployeePayment where Name in (0);
The OR expression evaluates to 0, and WHERE Name IN (0); returns all rows. You have to use the proper IN syntax as suggested in the other answers:
SELECT * FROM EmployeePayment WHERE Name IN ('foo', 'bar');
IN uses comma separated values, for example: WHERE Name IN ('tim','beth')
So try WHERE Name IN ('','');
But more importantly, why would you want to check where a value is empty or empty? Or was that just to get the question across?
http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_in

SQL group by - merge groups

Is it possible to "merge" 2 groups obtained after a SQL statement that use group by. For example if I have a field size ENUM('extra-small, 'small', 'medium', 'large', extra-large') and then I run this query SELECT * from clothes GROUP BY size;, but for in one case I would like to get in result "extra-small" and "small" in the same group. Is this possible with SQL?
yes, you can:
select count(*)
, case size
when 'extra-large'
then 'large'
else size end as grouped_size
from sizes
group by grouped_size
demo: http://sqlfiddle.com/#!2/ae3fa/2
How about using MySQL GROUP_CONCAT(expr)
This function returns a string result with the concatenated non-NULL
values from a group. It returns NULL if there are no non-NULL values.
Also have a look at MySQL – The GROUP_CONCAT() function