mysql comparison and encoding - mysql

I have a problem with MySQL here, it's quite strange actually... it's a real headbreak, I've been trying a lot of things, sticking some COLLATE, CAST, CONVERT,... but nothing, maybe i'm not doing it the right way, but I'm really lost here.
If some pro has a tip ;) here is my problem:
SELECT col FROM tabl LIMIT 0,1
returns: helloworld01
CASE WHEN((SELECT col FROM tabl LIMIT 0,1) = 'helloworld_01') THEN 'ok' ELSE 'ko' END
returns: ok
CASE WHEN(SUBSTR('helloworld_01',1,1) = 'h') THEN 'ok' ELSE 'ko' END
returns: ok
BUT and this is where it get strange
CASE WHEN(SUBSTR((SELECT col FROM tabl LIMIT 0,1),1,1) = 'h')
THEN 'ok' ELSE 'ko' END
returns: ko
after manually checking each letter i found that the result is quite strange ... numbers and letters in correct order but each character isn't the one supposed to be ... i get something like lsuejwodhb_65
.... but do not change at each request ... and they do not matche their CHAR code either ....

That's because in your below query it's not always guaranteed to output helloworld_01 unless you have only one row which is very rare; since you have not used any order by clause. So the data returned may be different and so your condition is not matching at all. To be sure use a order by clause. Again, without an order by using LIMIT clause makes no sense.
SELECT col FROM tabl order by col LIMIT 0,1
Try your strange query like below and see if it matches this time
CASE WHEN(SUBSTR((SELECT col FROM tabl order by col LIMIT 0,1),1,1) = 'h')
THEN 'ok' ELSE 'ko' END

Related

MYSQL Creating table as select with xase statement converting field to numbered value

I have the following MYSQL query which creates table as select statement but having a case statment to change field formats to numbered fields to compare:
CREATE TABLE wm.bochg
AS
SELECT
wca.bochg.BochgID,
wca.bochg.SecID,
wca.bochg.OldOutValue,
wca.bochg.NewOutValue,
case when NewOutValue+0.0 >= OldOutValue+0.0 then NewOutValue ELSE '' END AS test2
from wca.bochg
WHERE
wca.bochg.SecID in (select secid from client.pfisin where accid = 416)
AND (wca.bochg.BochgID is null or wca.bochg.BochgID =
(select subbochg.BochgID from wca.bochg as subbochg
where subbochg.secid=bochg.secid
AND subbochg.Actflag <> 'D'
AND subbochg.NewOutValue+0.0 >= subbochg.OldOutValue+0.0
order by subbochg.BochgID desc limit 1)
or wca.bochg.BochgID is NULL);
However I am getting warnings when this is created saying:
'Truncated incorrect DOUBLE value: '' '
This is due to my case statment and the and clause within my subquery. Is there a way to cater for this issue and get rid of the warning message above going forward? Thanks
You are mixing datatypes in the case statement. Use something else than a string '' for the ELSE part (NULL, 0 or anything that suits your purpose).

MySQL Proc OrderBy Case Not Allowing More Than One Column

I have a proc that needs to order the query by different fields depending on a parameter. To accomplish this I have created a simple case statement for my ORDER BY command which works great until I add a second sort field. I'm sure it's just a syntax issue, but I can't seem to find anything on this issue.
ORDER BY
CASE _sort
WHEN 'random' THEN RAND()
WHEN 'latest' THEN u.updated, ut.sort
WHEN 'alpha' THEN u.pageTitle, ut.sort
ELSE ut.sort
END
ASC
LIMIT _limit;
Adding the , ut.sort to each WHEN is what throws the error. When removed the proc works fine.
ORDER BY
CASE _sort WHEN 'random' THEN RAND()
WHEN 'latest' THEN u.updated
WHEN 'alpha' THEN u.pageTitle
ELSE 1
END, ut.sort

MySQL: How to use CASE for ORDER BY clause

I have a stored procedure that must return a table after filtering rows based on inputs. Two of the inputs are sort_column and sort_dir. The query must ORDER BY sort_column in the sort_dir direction(ASC or DESC).
I have tried the following queries but in vain. The queries below have been simplified to only contain the relevant clauses. The other filters work correctly with no issues.
SELECT * FROM table ORDER BY sort_column sort_dir
SELECT * FROM table ORDER BY CASE sort_column
WHEN 'col1' THEN col1_name
WHEN 'col2' THEN col2_name END
CASE sort_dir WHEN 'asc' THEN ASC
ELSE DESC END
I concatenated the 2 inputs to 1 in the format _ and tried this:
SELECT * FROM table ORDER BY CASE sort_input
WHEN 'col1_asc' THEN col1_name ASC
WHEN 'col1_desc' THEN col1_name DESC
WHEN 'col2_asc' THEN col2_name ASC
WHEN 'col2_desc' THEN col2_name DESC END
I always get error #1064. It is different in each of the above cases but always points to the 'CASE' part. This is the error for option number 2 mentioned above
##1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHEN 'col1' THEN col1_name END CASE 'asc' WHEN 'desc' THEN DESC ELSE ' at line 4
The problem doesn't seem to be the column name. It is the sort direction that isn't working. If I try each of the above options without the 'ASC' and 'DESC' parts, there is no problem.
Am I doing anything wrong here?
Is there a better way to go about this apart from CASE?
MySQL version: 5.6
The best approach is multiple cases:
ORDER BY (CASE WHEN sort_input = 'col1_asc' THEN col1_name END) ASC,
(CASE WHEN sort_input = 'col1_desc' THEN col1_name END) DESC,
(CASE WHEN sort_input = 'col2_asc' THEN col2_name END) ASC,
(CASE WHEN sort_input = 'col2_desc' THEN col2_name END) DESC,
This may seem verbose. But, remember that CASE is an expression that returns a single value. Hence you cannot include ASC and DESC as part of the THEN.
Also important is the issue of data types. The SQL compiler decides on a single type for CASE expression. This can cause unexpected issues when the columns have different types.
The simplest solution is just to use multiple CASE expressions.

mySQL Switch: How to give "OR" priority or importance in a SELECT statement to get a default row

Is there a simple way to do a Switch in mySQL? Consider this:
SELECT * FROM table WHERE
a=1 OR
b=2 OR
c=3 OR
d=4 OR
e=5 OR
f=6
LIMIT 1;
This will return a random row which matches any part of the OR clause. However, if a is the most important column, b is the next most important, etc, how do we alter the query to select only a single row in order of importance? In other words, we need to first check if a=1 and return it if true, else check b=2, and so on down the list until we find a hit.
The practical use for a query like this is a settings table where we want to see if the user or their administrator, or their organisation has added a custom settings row. If not, we need to select the default settings for that country.
I am thinking possibly of using the ORDER BY clause to return the most important row or maybe using a long messy if/else to find the most important result but I can't figure out the syntax.
This is very difficult to search so I've added some keywords to the title for SEO.
What you need here is ORDER BY CASE clause.
Like this:
SELECT * FROM table WHERE
a=1 OR
b=2 OR
c=3 OR
d=4 OR
e=5 OR
f=6
ORDER BY CASE WHEN a=1 THEN 0
WHEN b=2 THEN 1
WHEN c=3 THEN 2
...
ELSE 3
END
LIMIT 1;
You can use CASE, though this is getting ugly soon. It would be better to have your data normalized so you could query it better.
SELECT *
FROM table
WHERE
CASE WHEN a = 1
THEN a = 1
ELSE
CASE WHEN b = 2
THEN b = 2
ELSE
CASE WHEN c = 3
THEN c = 3
END END END
LIMIT 1;

MySQL query with WHERE clause, but drop a condition if no results?

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.