mysql query showing wrong result - mysql

I have a database table look like this
+======+===========+============+
| ID | user Name |user surname|
+======+===========+============+
| 100 | name | surname |
| 101 | name | surname |
| 102 | name | surname |
+===============================+
When i run this query which should show me no rows because there is no row with 101foo2 value :
SELECT * FROM tableName WHERE ID = '101foo2'
I am getting a result with same ID without the foo2 word
+======+===========+============+
| ID | user Name |user surname|
+======+===========+============+
| 101 | name | surname |
+===============================+
how it is showing the row with ID 101 if my query is ID = '101foo2'

You are mixing types. ID is an integer (or number). You are comparing it to a string. So, MySQL needs to decide what type to use for the comparison. What types gets used? Well, a string? No. A number. The string is converted to a number, using the leading digits. So, it becomes 101 and matches.
You should really only compare numbers to numbers, and strings to strings. You could try to write the code as:
SELECT * FROM tableName WHERE ID = 101foo2
However, you would get an error. Another possibility is to force the conversion to a string:
SELECT * FROM tableName WHERE CAST(ID as CHAR) = '101foo2'

Related

Why this sql is correct? (sql injection)

What does it mean?
SELECT * from users where password = ''*'';
if I check this in mysql workbench I get only one line, although I have lot of users in table.
What exactly does this select?
Interesting question. Let's see what ''*'' does.
mysql> select ''*'';
+-------+
| ''*'' |
+-------+
| 0 |
+-------+
Let's create some users:
mysql> select * from users;
+------+-------+
| id | name |
+------+-------+
| 1 | joe |
| 2 | moe |
| 3 | shmoe |
| 4 | 4four |
+------+-------+
And test our query:
mysql> select * from users where name = ''*'';
+------+-------+
| id | name |
+------+-------+
| 1 | joe |
| 2 | moe |
| 3 | shmoe |
+------+-------+
Interestingly enough, user 4 was not selected! But let's try this way:
mysql> select * from users where name = 4;
+------+-------+
| id | name |
+------+-------+
| 4 | 4four |
+------+-------+
So, what can we deduct from this?
''*'' somehow means 0 (I am not that fluent in mysql string operators, so let's take it as a fact);
MySQL, apparently, does type conversions in this case. So if you query a varchar column against an integer, it tries to convert those strings to ints and see if it's a match;
You have only one row whose password begins with 0 or non-digit.
You can always use an expression in SQL. Like SELECT 5-4 AS one and get 1. So you can tell that here is an expression.
MySQL is a loosely typed language, so it can multiply strings. Casting them to numbers. And get you zero as a result of '' * ''
When comparing a string with a number, MySQL casts both to a number. So 0 = 'name' condition will get you true
The ''*'' is a multiplication: its two arguments (empty strings) are converted to numericals (i.e. 0) and the result is 0. Then the left side of the equation is also converted to a number, which will sometimes be zero (when the password cannot be evaluated to a non-zero number), sometimes not.
It is a bit obscure, and you could ask yourself whether this was intended in your case or an accidental behaviour, while the actual intention was to test for '*'. A user with bad intentions might have entered '*' as a password hoping you were not protected against SQL injection in order to get into the system without a valid password.

How to SELECT values if id available in column(Comma separated values) using mysql?

How to SELECT values if id available in column(Comma separated values) using MySQL?
Here I need to get all values when the given id=17 available in group_id column.
Table:
+------------+---------------+
| user_id | group_id |
+------------+---------------+
| 1 | 1,2,3 |
| 3 | 12,23,17 |
| 5 | 17,26 |
+------------+---------------+
I try:
SELECT * FROM `group` WHERE units_id IN('17'); //No result
Expecting result:
+------------+---------------+
| user_id | group_id |
+------------+---------------+
| 3 | 12,23,17 |
| 5 | 17,26 |
+------------+---------------+
You can use FIND_IN_SET
SELECT * FROM `group` WHERE FIND_IN_SET(17,group_id);
Note: It's highly discouraged to store comma separated values in column. A must read:
Is storing a delimited list in a database column really that bad?
Yes
Also you shouldn't use MySQL reserved words as your identifer's name. Be careful to enclose by backtick while using.
Try this one.
You can use find_in_set :
SELECT * FROM `user` WHERE find_in_set('17',group_id) ORDER BY user_id;
RESULT:
+------------+---------------+
| user_id | group_id |
+------------+---------------+
| 3 | 12,23,17 |
| 5 | 17,26 |
+------------+---------------+
REF: MySQL query finding values in a comma separated string
You can use ´find_in_set`
SELECT * FROM `group` WHERE find_in_set('17',units_id );
IN checks if a column contains values from a comma separated list
It is very bad db design if you store values as csv.
For more infoemartion see mysql documentation

select rows has numeric length more than x

I have these values in a database under field name : username and table name : users
... | username | ...
--------------------------
| a651378 |
| b3789 |
| c3125621903 |
| d32168 |
| e789532 |
| f41589964312 |
For example how to select username where it has a number length greater than 6 digits
As the above values the query should return
... | username | ...
--------------------------
| c3125621903 |
| f41589964312 |
Try this:
SELECT * FROM users WHERE CHAR_LENGTH(username) > 7
CHAR_LENGTH function
Assuming that you do not know how long the character portions are, you can use regular expressions:
select u.*
from users u
where u.username regexp '^.*[0-9]{7}.*$';
Actually, this can be simplified to:
select u.*
from users u
where u.username regexp '[0-9]{7}';
When using regular expressions, I just like to be careful. LIKE patterns match the whole string (from the beginning to the end). REGEXP patterns match within a string.

MySQL query to SELECT rows with LIKE and create new column containing the matched string

I need some help with a MySQL query I am struggling for some time now.
So, I am trying to create a MySQL query to SELECT rows from a table that match a specific string like app.
My table is like this:
+-----+--------------+
| id | name |
+-----+--------------+
| 1 | Green Apple |
| 2 | Big Orange |
| 3 | application |
+-----+--------------+
I can find all rows that contain app string with SELECT and LIKE.
However, I also want to create new column that contains the string from name column which matches app and keep the database case sensitive format, i.e. with app as a match phrase the new column will contain App and app entires according to the string format in name.
My query so far goes like this:
SELECT *, 'what_to_put?' as new_column FROM table WHERE name LIKE '%".$app."%'
The desired output is the following:
+-----+--------------+-------------+
| id | name | new_column |
+-----+--------------+-------------+
| 1 | Green Apple | App |
| 2 | application | app |
+-----+--------------+-------------+
Any idea how to achieve this?
Without a separate regex library, you'll need to use the built-in string functions to find the location of the match, and then extract the matching sub-string:
SELECT
id,
name,
substring(name, locate('app', name), length('app')) as new_column
FROM yourTable
WHERE name LIKE '%app%'
Which gives the results:
+----+-------------+------------+
| id | name | new_column |
+----+-------------+------------+
| 1 | Green Apple | App |
| 3 | application | app |
+----+-------------+------------+
Sql Fiddle Here

MySQL Subselect issue

I have an issue with a mysql subselect.
**token table:**
id | token | articles
1 | 12345 | 7,6
2 | 45saf | 6,7,8
**items table:**
id | name | filename
6 | Some brilliant name | /test/something_useful.mp3
7 | homer simpson | /test/good-voice.mp3
**query:**
SELECT items.`filename`,items.`name` FROM rm_shop items WHERE items.`id` IN ( SELECT token.`articles` FROM rm_token token WHERE token.`token` = 'token')
I only get one of the two files (with the id 7 that is). What am I missing here?
For a column with concatenated data (like your "articles" column), you can not use MySQL IN() Function. Instead use the string function FIND_IN_SET() to query such values. In your case:
SELECT items.`filename`,items.`name` FROM rm_shop items
WHERE FIND_IN_SET(items.`id`,
(SELECT token.`articles` FROM rm_token token WHERE token.`token` = 'token')) > 0
A working sqlfiddle: http://sqlfiddle.com/#!2/796998/3/0