I have a forum, there's an option for user to change their names. Also i have staff members with names like [ADM]James. I want to prevent users to change his name in James.
Example: I have a memeber from staff with name [ADM]James, users should not be able to change his name in simply James.
There's my query : SELECT COUNT(*) FROM users WHERE name='James' LIKE '[%%' However this query return strange numbers it always return whole count of users.
What i do wrong?
EDIT, WHAT IS UNCLEAR?
I have 2 staff members. Admins and moderators, admins have tag name [ADM] moderators [MOD]. Example two names: [ADM]James [MOD]Jeff .. When a user try to change his name in James count should return 1. Because there is already one staff memeber with name [ADM]James.
CREATE TABLE `user` (
`id` int(0) NOT NULL AUTO_INCREMENT,
`user` varchar(24) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT 'NONAME',
) ENGINE = MyISAM AUTO_INCREMENT = 191782 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
Use below query,
SELECT COUNT(*) FROM users WHERE name LIKE '%]%'
SELECT user, COUNT(*) FROM users WHERE name LIKE '%[ADM]%' group by user;
SELECT COUNT(*) FROM users WHERE name LIKE '%James%'
Will count every name that has 'James' on it.
WHERE name='James' LIKE '[%%' is not a valid where clause
The syntax of the LIKE operator is expr LIKE pat [ESCAPE 'escape_char']
You can either use % or _
% matches any number of characters, even zero characters.
_ matches exactly one character.
Related
It states in the docs:
utf8_unicode_ci supports mappings such as expansions; that is, when one character compares as equal to combinations of other characters. For example, in German and some other languages “ß” is equal to “ss”.
I tried this out with an utf8mb4_unicode_ci collated table, with a row that has the name Heß.
select * from users where name = "Hess"
return the row with Heß. However, when I do the same with the like syntax
select * from users where name LIKE "%Hess%"
it returns no match.
Why does this happen and how does one fix it?
I have a simple mysql query which fetches AES_ENCRYPTED names from the table,
I want the result to show in alphabetical order,, but the problem is the result is showing capital results first..
I mean like
A
B
a
b
but I want like
A
a
B
b
this is my query..
select
id as id,
AES_DECRYPT(fname,'$_ENCKEY') as fname1,
AES_DECRYPT(lname,'$_ENCKEY') as lname
from patient
order by fname1 ASC
I also have tried LOWER, UPPER, UCASE etc.... but no luck...
And I am using PDO...
Try to cast the return value of AES_ENCRYPT to CHAR.
select
id as id,
CAST(AES_DECRYPT(fname,'$_ENCKEY') AS CHAR CHARACTER SET latin1 ) as fname1,
AES_DECRYPT(lname,'$_ENCKEY') as lname
from patient
order by fname1 collate latin1_general_cs
It's a case sensitive problem :
Try :
select
id as id,
AES_DECRYPT(fname,'$_ENCKEY') as fname1,
AES_DECRYPT(lname,'$_ENCKEY') as lname
from patient
order by fname1 COLLATE 'latin1_swedish_ci' ASC
I'm trying to find records that contain a string of 6 or more alpha-numeric characters in uppercase. Some examples:
PENDING 3RDPARTY CODE27
I'm using the following statement:
SELECT Details
FROM MyTable
WHERE Details LIKE '%[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]%';
This is returning all records that contain any 6-or-more-letter word, regardless of case.
I've added a COLLATE statement:
SELECT Details
FROM MyTable
WHERE Details COLLATE Latin1_General_CS_AS LIKE '%[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]%';
This changes nothing. It still returns records with 6-or-more-letter word, regardless of case.
Just as a test, I tried:
SELECT Details
FROM MyTable
WHERE Details COLLATE Latin1_General_CS_AS LIKE '%pending%';
SELECT Details
FROM MyTable
WHERE Details COLLATE Latin1_General_CS_AS LIKE '%PENDING%';
Both of these worked, returning records containing "pending" and "PENDING" respectively. So the issue seems to by the LIKE claus's pattern matching.
What can I do to perform this case-sensitive search?
Try using COLLATE Latin1_General_BIN rather than COLLATE Latin1_General_CS_AS
Update due to #GeraldSv: Use collation Latin1_General_BIN
SELECT Details
FROM MyTable
WHERE Details
LIKE '%[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]%'
COLLATE Latin1_General_BIN;
You need to place the collation specifier after the string to be matched rather than the column:
SELECT Details
FROM MyTable
WHERE Details
LIKE '%[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]%'
COLLATE Latin1_General_CS_AS;
Update: While my answer above is correct, there is a bug filed at Connect: Case-SENSITIVITY doesn't work when using a range in like with COLLATE Latin1_General_CS_AS which Microsoft have marked as 'By Design".
I verified by using AdventureWorks2008R2 (case insensitive, out of the box default), in the Person.Person table I changed 3 last names ending in 'n' to 'N', and then ran the following queries:
SELECT COUNT(*)
FROM Person.Person
WHERE LastName LIKE '%N' COLLATE Latin1_General_CS_AS
Success. Return 3 rows as expected.
SELECT COUNT(*)
FROM Person.Person
WHERE LastName LIKE '%[N]' COLLATE Latin1_General_CS_AS
Success. Return 3 rows as expected.
SELECT COUNT(*)
FROM Person.Person
WHERE LastName LIKE '%[N-N]' COLLATE Latin1_General_CS_AS
Success. Return 3 rows as expected.
SELECT COUNT(*)
FROM Person.Person
WHERE LastName LIKE '%[M-N]' COLLATE Latin1_General_CS_AS
Fails. Returns 3334 Rows (which is all Lastname's ending in 'n' and 'N')
Update: Thanks to #GeraldSv, this works:
SELECT COUNT(*)
FROM Person.Person
WHERE LastName LIKE '%[M-N]' COLLATE Latin1_General_BIN
I use the following:
SELECT COUNT(*)
FROM Person.Person
WHERE LastName COLLATE Latin1_General_CS_AS != upper(LastName) COLLATE Latin1_General_CS_AS
I have the following query:
SELECT *
FROM (
`teams`
)
WHERE `name` = 'mi equiñerolico'
And the result of this query is:
idteam|name|datet
9|mi equiñerolíco|2012-06-23 12:15:32
As you can see it retrieves a row with the name 'mi equiñerolíco' even though that my Where clause establish that it must be 'mi equiñerolico'.
teams table has utf8_general_ci collation.
How can I solve this ambiguity?
You could use a binary collation to force an accent-sensitve compare:
select *
from teams
where name = 'mi equiñerolico' collate utf8_bin
Currently I'm making my website application to validate the suburb values and ensure it exsits in the database data.
Here is my MySQL table
CREATE TABLE IF NOT EXISTS `postcodeTable` (
`id` int(11) NOT NULL,
`postcode` varchar(50) NOT NULL,
`suburb` text NOT NULL,
`state` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The user input 2 variables which are State and Suburb variable.
Here is my SQL statement to check if the row exists:
"select * from postcodeTable where state='".$state."' and suburb LIKE '%".$suburb."%'";
Here is my sample table data
Row1 id:1 postcode:3794 suburb: BANGHAM,BORDERTOWN,CANNAWIGARA,LOWAN, state: SA
Row2 id:2 postcode:6627 suburb: CANNA, state: WA
When a user input suburb CANNA and state SA it matches with the MySQL statement which is incorrect.
It matches because the LIKE statement because 'CANNA' word in CANNAWIGARA suburb name.
Which is incorrect because CANNA suburb only exist in WA state.
Is there a way to make the LIKE statement smarter which can go through the suburb string and ensure it matches the whole suburb name only?
Thanks so much in advance!
The problem here is your database schema : you should not store several suburbs in a single field of the postcodeTable table.
Instead, you should have one suburbs table, that would store one suburb per line, with a foreign key that points to the corresponding postcodeTable row.
Your postcodeTable table would be :
id
postcode
state
And your suburbs table would be :
id_suburb
id_postcode : foreign key to postcodeTable
name
Then, as suburbs.name would contain the exact name of one suburb, you wouldn't have to use like %...% anymore : you'd just have to use suburbs.name = '...'
And here's an idea of what your SQL query would look like :
select postcodeTable.*
from postcodeTable
inner join suburbs on suburbs.id_postcode = postcodeTable.id
where
suburbs.name = 'CANNA'
and postcodeTable.state = 'SA'
You could try regular expression matching. But I think it would be better to normalize your database. That is, split the suburbs off in a separate table, with a key pointing to the postcode table. Then you could do:
SELECT * FROM postcodeTable p
LEFT JOIN suburbTable s ON s.postcode_id = p.id
WHERE p.state = 'SA' AND s.name = 'CANNA';
Which should return zero rows.
If you need to search for exact comparisons, rather use
"select * from postcodeTable where state='".$state."' and suburb = $suburb
or drop the "%" at the back.
Have a look at the SQL Wildcards available: http://www.w3schools.com/sql/sql_wildcards.asp
If you don't want to modify your tables as people are suggesting, try:
"select * from postcodeTable where state='".$state."' and suburb LIKE '%".$suburb."%,'";
It will solve some problems, but not all of them.
Try:
$query = "select * from postcodeTable
where state='".$state."' and suburb REGEXP '(^|,)".$suburb."(,|$)'";
But as many others did, I strongly suggest you to normalize your schema.
Thanks for the responses!
Silly me I just realised if I just add a comma to the suburb field, it would solves the problem.
Since "comma" symbol in my suburb string means end of surburb word.
Cheers!
Thanks for the quick responses!
Silly me I just realised if I just add a comma to the suburb input field, it would solve the problem.
Since "comma" symbol in my suburb string means end of surburb word.
Thanks for your advices! I would normalise my Postcode table when I get the chance.
Cheers!