I want to do a query via phpmyadmin in which I can find any entries for Lastname that are not capitalized. Can I do that purely with sql?
If not: is there an easy way with php, or do I have to write code starting with substring()? Thanks.
Something like this should work
SELECT lastname
FROM tbl
WHERE CONCAT( UPPER( SUBSTRING( lastname, 1, 1 ) ) ,
LOWER( SUBSTRING( lastname FROM 2 ) ) ) != lastname Collate latin1_german2_cs;
The left side creates a proper-cased lastname, and compares it against the column case sensitively (using _cs collation)
According to MySQL doc, you could try:
SELECT * FROM your_table
WHERE your_field COLLATE <your_collation> REGEXP '[[:lower:]]+';
-- <your_collation> being a case sensitive collation,
-- such as latin1_general_cs, or utf8_bin, depending on your_table collation
Related
I am quite the novice at MYSQL and would appreciate any pointers - the goal here would be to automate a categorical field using GROUP_CONCAT in a certain way, and then summarize certain patterns in the GROUP_CONCAT field in a new_column. Furthermore, is it possible to add the new_column to the original table in one query? Below is what I've tried and errors to an unknown column "Codes" if this assists:
SELECT
`ID`,
`Code`,
GROUP_CONCAT(DISTINCT `Code` ORDER BY `Code` ASC SEPARATOR ", ") AS `Codes`,
IF(`Codes` LIKE '123%', 'Description1',
IF(`Codes` = '123, R321', 'Description2',
"Logic Needed"))
FROM Table1
GROUP BY `ID`
Instead of nested if statements, I would like to have a CASE statement as a substitute. Reason being is that I already have around 1000 lines of logical already written as "If [column] = "?" Then "?" else if" etc. I feel like using CASE would be an easier transition with the logic. Maybe something like:
SELECT
`ID`,
`Code`,
GROUP_CONCAT(DISTINCT `Code` ORDER BY `Code` ASC SEPARATOR ", ") AS `Codes`,
CASE
WHEN `Codes` LIKE '123%' THEN 'Description1'
WHEN `Codes` = '123, R321' THEN 'Description2'
ELSE "Logic Needed"
END
FROM Table1
GROUP BY `ID`
Table Example:
ID,Code
1,R321
1,123
2,1234
3,1231
4,123
4,R321
Completed Table:
ID,Codes,New_Column
1,"123, R321",Description2
2,1234,Description1
3,1231,Description1
4,"123, R321",Description2
How then can I add back the summarized data to the original table?
Final Table:
ID,Code,New_Column
1,R321,Description2
1,123,Description2
2,1234,Description1
3,1231,Description1
4,123,Description2
4,R321,Description2
Thanks.
You can't refer to a column alias in the same query. You need to do the GROUP_CONCAT() in a subquery, then the main query can refer to Codes to summarize it.
It also doesn't make sense to select Code, since there isn't a single Code value in the group.
SELECT ID, Codes,
CASE
WHEN `Codes` = '123, R321' THEN 'Description2'
WHEN `Codes` LIKE '123%' THEN 'Description1'
ELSE "Logic Needed"
END AS New_Column
FROM (
SELECT
`ID`,
GROUP_CONCAT(DISTINCT `Code` ORDER BY `Code` ASC SEPARATOR ", ") AS `Codes`
FROM Table1
GROUP BY ID
) AS x
As mentioned in a comment, the WHEN clauses are tested in order, so you need to put the more specific cases first. You might want to use FIND_IN_SET() rather than LIKE, since 123% will match 1234, not just 123, something
I'm trying to order at table with:
select * from my_table order by name
but something goes wrong, since:
IT is listed before Ib
For some reason capitalized letters are seen as more important?
Try this for case insensitive ordering:
SELECT * FROM `my_table` ORDER BY `name` COLLATE 'latin1_general_ci'
So I got a SQL statement. The idea is that I want to do a case-insensitive LIKE.
I do it like this:
SELECT
FilenameId AS id,
LOWER(CONVERT(BINARY(Filename.Name) USING utf8)) AS name
FROM Filename
WHERE name LIKE '%something%'
COLLATE utf8_general_ci
This works fine, however my query also returns the case-transformed name. What I want to do
is synthesize the insensitive name and do a LIKE query on it, but also return the non case-transformed name.
SELECT
FilenameId AS id,
Filename.Name AS name,
LOWER(CONVERT(BINARY(Filename.Name) USING utf8)) AS iname
FROM Filename
WHERE iname LIKE '%something%'
COLLATE utf8_general_ci
...but then MySQL happily refuses:
Unknown column 'iname' in 'where clause'
What am I doing wrong? I am on MySQL 5.5 FWIW.
I don't know why you came up with this, but usually others have trouble getting LIKE case sensitive, not the other way round.
Write your query simply like this:
SELECT
FilenameId AS id,
Filename.Name AS name
FROM Filename
WHERE name LIKE '%something%'
And in general, you can't access aliases in WHERE clause. Either put your query into a subquery like Dhinakaran suggested or use HAVING (if you are lazy).
The difference? WHERE is rowbased, HAVING works on the result after applying WHERE clause (and GROUP BY).
From the manual:
The following two statements illustrate that string comparisons are not case sensitive unless one of the operands is a binary string:
mysql> SELECT 'abc' LIKE 'ABC';
-> 1
mysql> SELECT 'abc' LIKE BINARY 'ABC';
-> 0
Create a sub query then put where on subquery
Select * from (SELECT
FilenameId AS id,
Filename.Name AS name,
LOWER(CONVERT(BINARY(Filename.Name) USING utf8)) AS iname
FROM Filename ) temp
WHERE temp.iname LIKE '%something%'
COLLATE utf8_general_ci
Or
SELECT
FilenameId AS id,
Filename.Name AS name,
AS iname
FROM Filename
WHERE LOWER(CONVERT(BINARY(Filename.Name) USING utf8)) LIKE '%something%'
COLLATE utf8_general_ci
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