I have 4cci and 4ccI values in database. When I run this query I get both rows.
select * from urls where url = "4cci";
How to do a case sensitive search?
Depend on your text field collation
Check the manual
mysql> SET #s1 = 'MySQL' COLLATE latin1_bin,
-> #s2 = 'mysql' COLLATE latin1_bin;
mysql> SELECT #s1 = #s2;
+-----------+
| #s1 = #s2 |
+-----------+
| 0 |
+-----------+
Use keyword BINARY before the column you want to perform case sensitive search
Description :
The BINARY function converts a value to a binary string.
Example
Suppose we have one table stores with 3 records where two recoard have country column as "IN" and one has as "in"
select count(*) from stores where BINARY country = 'in';
Output : count : 1
OR
Use CAST() function :
Description :
Convert a value to a DATE datatype:
select count(*) from stores where CAST(country AS BINARY) = 'IN';
Output : count : 2
How these function works :
Understand with simple example :
SELECT BINARY "HELLO" = "hello";
Output : 0
Here MySQL performs a byte-by-byte comparison of "HELLO" and "hello" and return 0 (because on a byte-by-byte basis, they are NOT equivalent):
Related
So I have a JSON variable with several values like this:
"["1", "2", "3", "4"]"
What i need to do is pass that value to an SQL procedure to mount a query in which the WHERE clause adds all the values in the JSON, so something like parsing the JSON, interate it and concat it in order to get an #where similar to:
AND id=1 AND id=2 AND id=3 AND id=4
I tried something like this, as something really similar is taking place in an already existing procedure, but doesn't work:
SET #idWhere="";
IF id IS NOT NULL AND JSON_EXTRACT(id, '$[0]') IS NOT NULL THEN
SET #idWhere = CONCAT(#idWhere," AND JSON_SEARCH('",id,"','one',id) IS NOT NULL ");
END IF;
Where id is both the name of the JSON and the column name.
Thanks in advance!
If you are running MySQL 8.0, you can use json_table() to turn the array to a recordset, and then aggregate the results with group_concat():
select group_concat(concat('id = ', i) separator ' and ') id_where
from json_table(
'["1", "2", "3", "4"]',
"$[*]" columns(i int path '$')
) as t
In this demo on DB Fiddle, this yields:
| id_where |
| --------------------------------------- |
| id = 1 and id = 2 and id = 3 and id = 4 |
NB: you probably want ors, not ands.
I have a field that is a longtext in MySQL. I'm looking for any instances of 'media' that could be in it, +/- ~10 characters of context. There are usually multiple instances in a single rows' field, so I need to see the context. How can I write a query to do this? I can't even think of where to start.
So what I'm looking at is this:
SELECT field_data_body FROM table WHERE field_data_body LIKE '%media%';
+----------------------------------+
| field_data_body |
+----------------------------------+
| ... ode__media_or ... e immediat |
+----------------------------------+
The field is actually a long string, and I just parsed the actual test value to show the substrings that would match the WHERE clause.
What I actually want to see is all instances of the string media, which in the example above is two, but in other fields could be more. SUBSTR only shows the first instance of media.
CREATE FUNCTION of your own. Inside the function you can use the WHILE statement and general string functions such as LOCATE and SUBSTRING.
Here is an example to get you started:
DELIMITER $$
CREATE FUNCTION substring_list(
haystack TEXT,
needle VARCHAR(100)
)
RETURNS TEXT
DETERMINISTIC
BEGIN
DECLARE needle_len INT DEFAULT CHAR_LENGTH(needle);
DECLARE output_str TEXT DEFAULT '';
DECLARE needle_pos INT DEFAULT LOCATE(needle, haystack);
WHILE needle_pos > 0 DO
SET output_str = CONCAT(output_str, SUBSTRING(haystack, GREATEST(needle_pos - 10, 1), LEAST(needle_pos - 1, 10) + needle_len + 10), '\n');
SET needle_pos = LOCATE(needle, haystack, needle_pos + needle_len);
END WHILE;
RETURN output_str;
END$$
DELIMITER ;
Here are some tests. For each match, the term ("media") and up to 10 characters on either side are returned, all concatenated in a single string:
SELECT substring_list('1234567890media12345678immediate34567890media1234567890', 'media');
+---------------------------+
| 1234567890media12345678im |
| 12345678immediate34567890 |
| te34567890media1234567890 |
+---------------------------+
SELECT substring_list('0media12345678immediate34567890media1', 'media');
+---------------------------+
| 0media12345678im |
| 12345678immediate34567890 |
| te34567890media1 |
+---------------------------+
In mysql you can create a user define function for this like wordcount. You can get help from this UDF.
mysql count word in sql syntax
Here is a solution using PHP that will return each row and each result plus the surrounding characters in a multidimensional array.
$value = "media";
$surroundingChars = 5;
$strlen = strlen($value);
$stmt = $pdo->prepare("SELECT field_data_body FROM table WHERE field_data_body LIKE ?";
$stmt->execute([ '%'.$value.'%' ]);
$result = 0;
while ($body = $stmt->fetchColumn()) {
$start = 0;
while (($pos = stripos($body, $value, $start)) !== FALSE) {
$return[$result][] = substr($body, $pos - $surroundingChars, $strlen + ($surroundingChars * 2));
// Adjust next start
$start = $pos + $strlen;
}
$result++;
}
You could always change the $return[$result][] line, but to echo all rows in the format you wanted, you could do this:
foreach($return as $row) {
echo implode('..', $row);
}
As you stated in the comments, you'd rather a query, but if you change your mind, here is a solution matching your PHP requirements.
I have a table in mysql with many columns and I want to see maximum length of values. My purpose is that I do know that some of data is truncated when insert and I want to increase varchar length. But do not know, what columns. (Explanation little messy, but probably sql will make sense)
I tried:
select COLUMN_NAME, CHARACTER_MAXIMUM_LENGTH, DATA_TYPE, (SELECT LENGTH(COLUMN_NAME) as maxlen FROM my_database.my_table ORDER BY maxlen DESC LIMIT 1)
from information_schema.columns
where table_schema = 'my_database' AND
table_name = 'my_table'AND DATA_TYPE = 'varchar'
It works, but return the length of the column, but not data inside it. (I.e. id column is called id, I got 2).
If I use JOIN (ON TRUE condition), I got error that COLUMN_NAME is undefined.
Stored procedures does not allow for data return, and function does not allow dynamic sql inside it.
How to tell MySQL (in case of my query) to consider COLUMN_NAME not as a string, but as column name? If this is not, possible in select, how to get columns with maximum data inside them?
Desired result looks like:
column_1 | 25 | varchar | 20
column_2 | 25 | varchar | 7
I am interested only in varchar, as int does not make sense to adjust (and no need to). Columns has different length (varchar(20),varchar(25), etc.).
Update 1: This cannot be done also via loop (statements cannot be executed inside cursor).
I use something like this type of code to generate my view automticaly using table schema. Use can modify according to your need.
$sql = "show tables from DBName where Tables_in_yourtbalename = 'yourtbalename' ";
$result = executeQuery($sql, $conn);
$num = $result->num_rows;
if ($num) {
$sql = "show columns from yourtbalename where Extra != 'auto_increment'";
$result = executeQuery($sql, $conn);
$num2 = $result->num_rows;
while ($r = $result->fetch_assoc()) {
if ($r['Key'] == 'MUL' && ( preg_match("/^int/", $r['Type']) || preg_match("/^smallint/", $r['Type']) || preg_match("/^tinyint/", $r['Type']) || preg_match("/^bigint/", $r['Type']))) {
} else if ($r['Field'] == 'status') {
}
}
Where $r['Field'] is field name and $r['Type'] provides its type. For determining maxlength use
$maxlength="' . substr(str_replace(")", "", $r['Type']), 8, (strlen(str_replace(")", "", $r['Type']))));
Query =
SELECT * FROM options WHERE 'key' = 'exchange_rate'
Table structure =
key varchar(500) latin1_swedish_ci
value text latin1_swedish_ci
Table content
Key | Value
exchange_rate | 25
Program
phpMyAdmin 4.0.4 Mysql
Result
0 Rows returned
Do you know what the problem is here?
try this query:
SELECT * FROM options WHERE `key` = 'exchange_rate'
instead of :
SELECT * FROM options WHERE 'key' = 'exchange_rate'
Qoutes are used to show varchar values not column name
SELECT * FROM options WHERE `key` = 'exchange_rate'
suppose the user input
mysite.com/profile?identity=1
mysite.com/profile?identity=dinodsja
mysite.com/profile?identity=1a
getting the value
$identity = $_GET['identity']; // identity can be user_id or user_name
and i have a simple select query:
SELECT * FROM lb_users WHERE (user_id = 'dinodsja' OR user_name = 'dinodsja') AND user_status = 1
and it works fine. but the problem is:
SELECT * FROM lb_users WHERE (user_id = '1a' OR user_name = '1a') AND user_status = 1
when I execute this query it also returns the result without satisfying the condition.
Table structure:
user_id bigint(25)
user_name varchar(50) utf8_general_ci
**
-> Is this a MySQL Bug ?
-> How can we avoid this ?
-> What will be the query ?
**
The reason for that is because the data type of the column user_ID is integer.
MySQL silently drops any trailing NON-Number (and anything that follows within) in the value and that is why 1a is equal to 1 since a will be remove in the value.
SQLFiddle Demo
I do remember having a similar problem long ago.
First some background: This is not a bug. It is actually a feature. Ok, it's one that might lead to such unexpected behaviour, but MySQL is thereby very tolerant w.r.t. user inputs, respective select queries:
mysql> SELECT 'a' = 'a ';
-> 1
mysql> SELECT 'A' = 'a';
-> 1
Therefore, with implicit type conversion, the result of, e.g, '1a' in INTEGER is 1, but also:
mysql> SELECT 0 = 'x6';
-> 1
mysql> SELECT 1 = ' 1';
-> 1
mysql> SELECT 1 = ' 1a';
-> 1
This feature is also implemented in other not statically typed languages. PHP, for instance, calls this type juggling. See the PHP String conversion rules and this example from the documentation:
<?php
$foo = "0"; // $foo is string (ASCII 48)
$foo += 2; // $foo is now an integer (2)
$foo = $foo + 1.3; // $foo is now a float (3.3)
$foo = 5 + "10 Little Piggies"; // $foo is integer (15)
$foo = 5 + "10 Small Pigs"; // $foo is integer (15)
?>
See JavaScript:
<script>
document.write(parseInt("40 years") + "<br>");
</script>
=> 40
Nevertheless, the solution to your problem is pretty easy: Just cast the integer to a char and do the comparison then:
mysql> SELECT * FROM lb_users WHERE (CAST(user_id AS CHAR) = '1' OR user_name = '1')
-> 1
mysql> SELECT * FROM lb_users WHERE (CAST(user_id AS CHAR) = '1a' OR user_name = '1a')
-> 0
mysql> SELECT * FROM lb_users WHERE (CAST(user_id AS CHAR) = 'dinodsja' OR user_name = 'dinodsja')
-> 1
I made a fiddle for everyone to try it out: http://sqlfiddle.com/#!2/c2835/14/0
Hope that helps,
-Hannes
According to your previous message
its a user input for profile. user can provide user_id or user_name.
so the input is valid. but no data. – DBK Mar 30 at 6:42
I'd recommend testing to see if its an integer and only search the user ID if it's an integer. It's really more of a workaround for mySQL not handling a STRING to INT comparison, but it should work.
declare #InputVar varchar(10)
set #InputVar = '1a'
SELECT *
FROM lb_users
WHERE
(case when isnumeric(#InputVar) = 1 then
case when (user_id = #InputVar OR user_name = #InputVar) then 1 else 0 end
else
case when user_name = #InputVar then 1 else 0 end
end =1 )
And
user_status = 1
When dealing with strings I would use 'LIKE' instead of '=' to avoid this silent type conversion madness. LIKE is made to work with strings so why not use it.
SELECT * FROM lb_users WHERE (user_id = '1a' OR user_name = '1a') AND user_status = 1
you get 1 result if you change '1a' to 1a you get this:
#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 '1a LIMIT 0, 30' at line 1
This is not a bug, take a look at http://dev.mysql.com/doc/refman/5.0/en/where-optimizations.html
hope this helps
I think you cannot duplicate a primary key and an ID, I test that one and i come up with a running data..did you set the user_id with its attributes like:
user_id bigint(50) auto_increment primary key
this is not a mysql error.