SQL query does not perform DESC correctly - mysql

I have a problem that I do not know how to solve.
I have this query:
$sql = "SELECT * FROM transfer_centre WHERE status = 'out' ORDER BY pris DESC";
And I have four values as pris in my db:
0, 4, 8, 26
So, as the query states they should be listed as such:
26
8
4
0
But somehow it sees the 26 value as 2.6 (i guess?) and therefore 26 is between 4 and 0?
Can someone help me with this issue?

It looks like your column is a VARCHAR type and it is ordering like it. When you order a VARCHAR, you go from left to right on each character, so 26 is between 0 and 4.
You can try this, if you can't change your schema:
SELECT * FROM transfer_centre WHERE status = 'out'
ORDER BY CAST(pris as SIGNED INTEGER) DESC
NOTE: This is not even close from an ideal solution! If the column is treated as a number, you should change the schema applying the right type.

Related

Get least 10 values in mysql query

I have a table in mysql. Table Name is constitutive_table, it contains more than 40 columns and its type is varchar, it contains more than 25000 records. I wrote the query like this to get the 10 least value. But it showing like as you have seen in the picture.
SELECT `Sequence_Name`
, `Name_of_the_Protein`
, `Brain`
FROM `constitutive_table`
where `Brain` != 0
ORDER
BY cast(Brain AS int)
LIMIT 0,10
The data in the Brain column appears to be floating point, so you should be casting to the appropriate type:
SELECT Sequence_Name, Name_of_the_Protein, Brain
FROM constitutive_table
WHERE CAST(Brain AS DECIMAL(14, 8)) <> 0
ORDER BY CAST(Brain AS DECIMAL(14, 8))
LIMIT 10
Most likely what is happening now is that the 10 values you see all have the same value when cast to integer. As a result, MySQL is using some secondary sort to generate the order you do see.
While the above query may resolve your problem, ideally you should change the Brain column to some numeric type.

MySQL in clause slow with 10 or more items

This query takes 18 seconds
SELECT `wd`.`week` AS `start_week`, `wd`.`hold_code`, COUNT(wd.hold_code) AS hold_code_count
FROM `weekly_data` AS `wd`
JOIN aol_reporting_hold_codes hc ON hc.hold_code = wd.hold_code AND chart = 'GR'
WHERE `wd`.`days` <= 6
AND `wd`.`hold_code` IS NOT NULL
AND NOT `wd`.`hold_code` = ''
AND `wd`.`week` >= '201717'
AND `wd`.`itemgroup` IN ('BOTDTO', 'BOTDWG', 'C&FORG', 'C&FOTO', 'MF-SUB', 'MI-SUB', 'PROPRI', 'PROPTO', 'STRSTO', 'STRSUB')
AND `production_type` = 2
AND `contract` = "1234"
AND `project` = 8
GROUP BY `start_week`, `wd`.`hold_code`
This query takes 4 seconds
SELECT `wd`.`week` AS `start_week`, `wd`.`hold_code`, COUNT(wd.hold_code) AS hold_code_count
FROM `weekly_data` AS `wd`
JOIN aol_reporting_hold_codes hc ON hc.hold_code = wd.hold_code AND chart = 'GR'
WHERE `wd`.`days` <= 6
AND `wd`.`hold_code` IS NOT NULL
AND NOT `wd`.`hold_code` = ''
AND `wd`.`week` >= '201717'
AND `wd`.`itemgroup` IN ('BOTDWG', 'C&FORG', 'C&FOTO', 'MF-SUB', 'MI-SUB', 'PROPRI', 'PROPTO', 'STRSTO', 'STRSUB')
AND `production_type` = 2
AND `contract` = "1234"
AND `project` = 8
GROUP BY `start_week`, `wd`.`hold_code`
All I have done is removed one item from the IN clause. I can remove any one of the items. It runs in 4 seconds as long as there are 9 items or less. It takes 18 seconds to run as soon as I increase to 10 items.
I thought MySQL limited length of command by size i.e. 1MB
More than just the EXPLAIN, use EXPLAIN FORMAT=JSON and get the "Optimizer trace" for the query. I suspect the length of the IN leads to picking a different query plan.
There is virtually no limit to the number of items in IN. I have seen as many as 70K.
That aside, you may be able to speed up even the 4-sec version...
I suggest having this index. Grrr... I can't tell which columns are in which tables. So, if these are all in one table, then make such an index:
INDEX(production_type, contract, project) -- in any order
If those are all in wd, then tack on a 4th column - any of week, itemgroup, days.
Be cautious about COUNT(wd.hold_code).
COUNT(x) checks x for being non-NULL; is that what you want? If not, then simply say COUNT(*).
When JOINing, then GROUP BY, you get an "explode-implode". The number of intermediate rows is big; that is when the COUNT is performed.
It seems wrong to both COUNT(hold_code) and GROUP BY hold_code. What are you trying to do?
For further discussion, please provide SHOW CREATE TABLE and EXPLAIN.
Please note MySql IN clause limit is established with max_allowed_packet value. You may check with NOT IN if results are faster. Also I suggest put values to be checked with IN clause under a buffer string instead of comma separated values and then give a try.

selecting BIT field in sub query gives '49' instead of 0 or 1

select *, (select logactivity from users where regtoken= '12345') as log from server
the log activity field in 'users' is a BIT field which under "SELECT * FROM USERS" comes up 0 or 1. But when I use the subquery above, I get 49 instead of 1, 48 instead of 0. Why?
48 and 49 are integer values of character (ascii) representations of characters0 and 1 .
Perhaps the issue is not in your query, but in your code somewhere which deals with this case.
php example : http://codepad.org/5i65IWTG

Need a help for sort in mysql

Hi I want to sort a table .The field contains numbers,alphabets and numbers with alphabets ie,
1
2
1a
11a
a
6a
b
I want to sort this to,
1
1a
2
6a
11a
a
b
My code is, SELECT * FROM t ORDER BY CAST(st AS SIGNED), st
But the result is,
a
b
1
1a
2
6a
11a
I found this code in this url "http://www.mpopp.net/2006/06/sorting-of-numeric-values-mixed-with-alphanumeric-values/"
Anyone please help me
This would do your required sort order, even in the presence of 0 in the table;
SELECT * FROM t
ORDER BY
st REGEXP '^[[:alpha:]].*',
st+0,
st
An SQLfiddle to test with.
As a first sort criteria, it sorts anything that starts with a letter after anything that doesn't. That's what the regexp does.
As a second sort criteria it sorts by the numerical value the string starts with (st+0 adds 0 to the numerical part the string starts with and returns an int)
As a last resort, it sorts by the string itself to get the alphabetical ones in order.
You can use this:
SELECT *
FROM t
ORDER BY
st+0=0, st+0, st
Using st+0 the varchar column will be casted to int. Ordering by st+0=0 will put alphanumeric rows at the bottom (st+0=0 will be 1 if the string starts with an alphanumeric character, oterwise it will be 0)
Please see fiddle here.
The reason that you are getting this output is that all the character like 'a', 'b' etc are converted to '0' and if you use order by ASC it will appear at the top.
SELECT CAST(number AS SIGNED) from tbl
is returning
1
2
1
11
0
6
0
Look at this fiddle:- SQL FIDDLE
I did small change in your query -
SELECT *, CAST(st AS SIGNED) as casted_column
FROM t
ORDER BY casted_column ASC, st ASC
this should work.
in theory your syntax should work but not sure why mysql doesn't accept these methods after from tag.
so created temp field and then sorted that one .
This should work as per my experience, and you can check it.
SQL FIDDLE

How to return all matches in mysql where value occurs in string at position n?

Im looking to run a query in phpmyadmin (mysql) that wil check a table for a specific value at a specific postion in a string, i'm new to mysql and this is what i've tried but there's a syntax issue. I'm looking to find the value "1" at position 5 and display all those users that possess this.
SELECT*
FROM`user`
WHERE`options`LOCATE(`options`,1,5)
LIMIT 0 , 30
regards,
Silo
Locate is for finding a value ANYWHERE in a string. You want a specific location only, so use substr() instead:
SELECT *
FROM user
WHERE substr(options, 5, 1) = '1'
You could try
SELECT*
FROM`user`
WHERE options LIKE '____1%'
LIMIT 0 , 30
Another ;)
SELECT *
FROM user
WHERE instr(options, '1') = 5
Duh .. Well won't work since it only returns the first occurnace :$ But CHECK the reference,
SQLFIDDLE using Locate()
Sample data:
COL1 COL2
G11 112
G11-1 0
G11-2 2
G12-2 111
Query1:
-- to check on varchar columns
SELECT *
FROM tablex
where locate('1',col1,5)
;
Results on varchar:
COL1 COL2
G11-1 0
Query 2:
-- to check on int columns
SELECT *
FROM tablex
where locate(1,col2,2)
;
Results on int:
COL1 COL2
G11 112
G12-2 111