MySQL MIN & MAX on alpha numeric column - mysql

Simple MAX query:
SELECT MAX(Group) FROM acme
Works fine on a numeric column.
Is it possible to use to this on an alpha-numeric column and ignore anything other than a number?

yes if you cast it before use like this
mysql> SELECT MAX(CAST("123" AS UNSIGNED));
+------------------------------+
| MAX(CAST("123" AS UNSIGNED)) |
+------------------------------+
| 123 |
+------------------------------+
1 row in set (0.00 sec)
mysql> SELECT MAX(CAST("abc" AS UNSIGNED));
+------------------------------+
| MAX(CAST("abc" AS UNSIGNED)) |
+------------------------------+
| 0 |
+------------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> SELECT MAX(CAST("-123" AS SIGNED));
+-----------------------------+
| MAX(CAST("-123" AS SIGNED)) |
+-----------------------------+
| -123 |
+-----------------------------+
1 row in set (0.00 sec)
replace your string column name with "abc" and modify query acording to your requirment

Related

Search for a text containing backslash in MySQL

I have a mysql table with 2 entries (id ,title) (int, text)
A row of dummy data in the table looks like
id title
1 apple\"apple
My query intends to do a search on the field title
select * from table1 where title='apple\"apple';
I also tried using
select * from table1 where title like('apple\"apple');
The above query did not seem to work as well.
Both queries are returning an empty sets. Is it not possible to search for a string that has backslash in it?
PS :: The \ is added to the DB as part of escaping the double quotes.
Sure? It works as expected.
mysql> CREATE TABLE MyTbl (id INT, title TEXT);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO MyTbl VALUES(1,'apple "apple');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM MyTbl;
+------+-------------+
| id | title |
+------+-------------+
| 1 | apple"apple |
+------+-------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM MyTbl WHERE title = 'apple \"apple';
+------+-------------+
| id | title |
+------+-------------+
| 1 | apple"apple |
+------+-------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM MyTbl WHERE title like('apple \"apple');
+------+-------------+
| id | title |
+------+-------------+
| 1 | apple"apple |
+------+-------------+
1 row in set (0.00 sec)
Maybe Is it something related to the space character?
mysql> SELECT * FROM MyTbl WHERE title = 'apple\"apple';
Empty set (0.00 sec)
mysql> SELECT * FROM MyTbl WHERE title = 'apple \"apple';
+------+--------------+
| id | title |
+------+--------------+
| 1 | apple "apple |
+------+--------------+
1 row in set (0.00 sec)
What about running this command? What It returns for you?
mysql> SELECT #NO_BACKSLASH_ESCAPES;
+----------------------------------------------+
| #NO_BACKSLASH_ESCAPES |
+----------------------------------------------+
| NULL |
+----------------------------------------------+
1 row in set (0.00 sec)

Find and replace a specific part of a string with a backslash in a field

For example this is myTable:
| i | data |
+---+---------+
| 1 | d\one |
| 2 | d\two |
| 3 | d\three |
But I want to change it to:
| i | data |
+---+-------+
| 1 | one |
| 2 | two |
| 3 | three |
I know how to find a specific part of a string with a backslash in a field:
SELECT * FROM myTable WHERE data LIKE 'd%\%'
I know how to find & replace a field a value, only this query won't work:
UPDATE myTable SET data=REPLACE(data,'d\','') WHERE data LIKE 'd%\%'
You need to escape the backslash
UPDATE myTable
SET data = REPLACE(data,'d\\','')
WHERE data INSTR('d\\') = 1
SQLFiddle demo
I hope you should put triple slash \\\ instead of double slash \\ in Like Clause. As I have tried I am unable to pick data from using \\
SELECT * FROM mytable WHERE data LIKE 'd\\%';
Empty set (0.00 sec)
mysql> SELECT * FROM mytable WHERE data LIKE 'd\\\%';
+---------+
| data |
+---------+
| d\one |
| d\two |
| d\three |
+---------+
3 rows in set (0.00 sec)
mysql> SELECT REPLACE(data,'d\\','') FROM mytable WHERE data LIKE 'd\\\%';
+------------------------+
| REPLACE(data,'d\\','') |
+------------------------+
| one |
| two |
| three |
+------------------------+
3 rows in set (0.00 sec)
mysql> UPDATE mytable SET data = REPLACE(data,'d\\','') WHERE data LIKE 'd\\\%';
Query OK, 3 rows affected (0.06 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> SELECT * FROM mytable;
+-------+
| data |
+-------+
| one |
| two |
| three |
+-------+
3 rows in set (0.00 sec)
try this one..
UPDATE myTable SET `data`=REPLACE(`data`,'d\','');

Slow InfiniDB queries, what am I doing wrong?

I'm testing the InfiniDB community edition to see if it suits our needing.
I imported in a single table about 10 millions rows (loading of data was surprisingly fast), and I'm trying to do some query on it, but these are the results (with NON cached queries.. if query caching exists in InfiniDB):
Query 1 (very fast):
select * from mytable limit 150000,1000
1000 rows in set (0.04 sec)
Query 2 (immediate):
select count(*) from mytable;
+----------+
| count(*) |
+----------+
| 9429378 |
+----------+
1 row in set (0.00 sec)
Ok it seems to be amazingly fast.. but:
Query 3:
select count(title) from mytable;
.. still going after several minutes
Query 4:
select id from mytable where id like '%ABCD%';
+------------+
| id |
+------------+
| ABCD |
+------------+
1 row in set (11 min 17.30 sec)
I must be doing something wrong, it's not possible that it's performing this way with so simple queries. Any Idea?
That shouldn't be the case, there does appear to be something odd going on, see quick test below.
What is your server configuration: memory/OS/CPU and platform (dedicated, virtual, cloud).
Could I get the schema declaration and method to load the data?
Which version are you using? Version 4 community has significantly more features than prior versions, i.e. core syntax matches enterprise.
Cheers,
Jim T
mysql> insert into mytable select a, a from (select hex(rand() * 100000) a from lineitem limit 10000000) b;
Query OK, 10000000 rows affected (1 min 54.12 sec)
Records: 10000000 Duplicates: 0 Warnings: 0
mysql> desc mytable;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | varchar(32) | YES | | NULL | |
| title | varchar(32) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
mysql> select * from mytable limit 150000,1000;
+-------+-------+
| id | title |
+-------+-------+
| E81 | E81 |
| 746A | 746A |
. . .
| DFC8 | DFC8 |
| 2C56 | 2C56 |
+-------+-------+
1000 rows in set (0.07 sec)
mysql> select count(*) from mytable;
+----------+
| count(*) |
+----------+
| 10000000 |
+----------+
1 row in set (0.06 sec)
mysql> select count(title) from mytable;
+--------------+
| count(title) |
+--------------+
| 10000000 |
+--------------+
1 row in set (0.09 sec)
mysql> select id from mytable where id like '%ABCD%' limit 1;
+------+
| id |
+------+
| ABCD |
+------+
1 row in set (0.03 sec)

what is the meaning of select ''-''

There is an article about SQL injection: Abusing MySQL string arithmetic for tiny SQL injections
The question is, what is the meaning of select ''-'' ? I try it with MySQL, and it returns:
mysql> select ''-'';
+-------+
| ''-'' |
+-------+
| 0 |
+-------+
1 row in set (0.00 sec)
What happend? What means that 0?
And the result of select '-':
mysql> select '-';
+---+
| - |
+---+
| - |
+---+
1 row in set (0.00 sec)
I am very confused about these result.
You are minus - from one empty string '' to other:
See following:
mysql> select '';
+--+
| |
+--+
| |
+--+
1 row in set (0.00 sec)
mysql> select '3'-'2';
+---------+
| '3'-'2' |
+---------+
| 1 |
+---------+
1 row in set (0.00 sec)
But warning if its not a number string:
mysql> select 'a'-'b';
+---------+
| 'a'-'b' |
+---------+
| 0 |
+---------+
1 row in set, 2 warnings (0.00 sec)
Two warnings:
mysql> SHOW WARNINGS LIMIT 2
-> ;
+---------+------+---------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: 'a' |
| Warning | 1292 | Truncated incorrect DOUBLE value: 'b' |
+---------+------+---------------------------------------+
2 rows in set (0.00 sec)
Why no warning for empty string?
Where as there is no warning for empty string because its(casted something) 0 see below:
mysql> SELECT 0 = '';
+--------+
| 0 = '' |
+--------+
| 1 |
+--------+
1 row in set (0.00 sec)
hence by doing ''-'' you are doing 0 - 0
mysql> SELECT '' - '';
+---------+
| '' - '' |
+---------+
| 0 |
+---------+
1 row in set (0.00 sec)
To be more clear I am adding following example (I feels will be helpful to you):
How conversion happen:
mysql> SELECT '0' = 0
-> ;
+---------+
| '0' = 0 |
+---------+
| 1 |
+---------+
1 row in set (0.00 sec)
notice its conversion:
mysql> SELECT '' = '0'
-> ;
+----------+
| '' = '0' |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)
'' converted into 0, '0' converted into 0 but '' not equals to '0'
mysql> SELECT '1' = 1
-> ;
+---------+
| '1' = 1 |
+---------+
| 1 |
+---------+
1 row in set (0.00 sec)
mysql> SELECT '' = 1
-> ;
+--------+
| '' = 1 |
+--------+
| 0 |
+--------+
1 row in set (0.00 sec)
I'd explain select ''-'', which is the same as select '' - '', as select cast('' as int) - cast('' as int) which is select 0-0..
With select '-' you just get a string. Hope that makes sense...
'' is an empty string; - is subtraction. So you're subtracting one empty string from another. Subtraction is a numeric operator, so its result is a number, and mysql converts its arguments into numbers before subtracting them. The numeric value of '' is zero — but it doesn't matter very much, since any number subtracted from itself is going to give zero anyway.

MySQL LIKE vs LOCATE

Does anyone know which one is faster:
SELECT * FROM table WHERE column LIKE '%text%';
or
SELECT * FROM table WHERE LOCATE('text',column)>0;
Added April 20th, 2015: Please read also Hallie's answer below
First one but marginally. Mostly because it doesn't have to do an extra > 0 comparison.
mysql> SELECT BENCHMARK(100000000,LOCATE('foo','foobar'));
+---------------------------------------------+
| BENCHMARK(100000000,LOCATE('foo','foobar')) |
+---------------------------------------------+
| 0 |
+---------------------------------------------+
1 row in set (3.24 sec)
mysql> SELECT BENCHMARK(100000000,LOCATE('foo','foobar') > 0);
+-------------------------------------------------+
| BENCHMARK(100000000,LOCATE('foo','foobar') > 0) |
+-------------------------------------------------+
| 0 |
+-------------------------------------------------+
1 row in set (4.63 sec)
mysql> SELECT BENCHMARK(100000000,'foobar' LIKE '%foo%');
+--------------------------------------------+
| BENCHMARK(100000000,'foobar' LIKE '%foo%') |
+--------------------------------------------+
| 0 |
+--------------------------------------------+
1 row in set (4.28 sec)
mysql> SELECT ##version;
+----------------------+
| ##version |
+----------------------+
| 5.1.36-community-log |
+----------------------+
1 row in set (0.01 sec)
+1 to #Mchl for answering the question most directly.
But we should keep in mind that neither of the solutions can use an index, so they're bound to do table-scans.
Trying to decide between a cloth or plastic adhesive bandage is kind of silly, when you're trying to patch the hull of the Titanic.
For this type of query, one needs a full-text search index. Depending on the size of the table, this will be hundreds or thousands of times faster.
I did some tests as Mchi did.And I think it's hard to say which one is faster. It looks like depending on the first occurrence of the substring.
mysql> select benchmark(100000000, 'afoobar' like '%foo%');
+----------------------------------------------+
| benchmark(100000000, 'afoobar' like '%foo%') |
+----------------------------------------------+
| 0 |
+----------------------------------------------+
1 row in set (9.80 sec)
mysql> select benchmark(100000000, locate('foo', 'afoobar'));
+------------------------------------------------+
| benchmark(100000000, locate('foo', 'afoobar')) |
+------------------------------------------------+
| 0 |
+------------------------------------------------+
1 row in set (8.08 sec)
mysql> select benchmark(100000000, 'abfoobar' like '%foo%');
+-----------------------------------------------+
| benchmark(100000000, 'abfoobar' like '%foo%') |
+-----------------------------------------------+
| 0 |
+-----------------------------------------------+
1 row in set (10.55 sec)
mysql> select benchmark(100000000, locate('foo', 'abfoobar'));
+-------------------------------------------------+
| benchmark(100000000, locate('foo', 'abfoobar')) |
+-------------------------------------------------+
| 0 |
+-------------------------------------------------+
1 row in set (10.63 sec)
mysql> select benchmark(100000000, 'abcfoobar' like '%foo%');
+------------------------------------------------+
| benchmark(100000000, 'abcfoobar' like '%foo%') |
+------------------------------------------------+
| 0 |
+------------------------------------------------+
1 row in set (11.54 sec)
mysql> select benchmark(100000000, locate('foo', 'abcfoobar'));
+--------------------------------------------------+
| benchmark(100000000, locate('foo', 'abcfoobar')) |
+--------------------------------------------------+
| 0 |
+--------------------------------------------------+
1 row in set (12.48 sec)
mysql> select ##version;
+------------+
| ##version |
+------------+
| 5.5.27-log |
+------------+
1 row in set (0.01 sec)