Finding MySQL fields ending in spaces - mysql

After a database import, there's some rows with dirty fields that end in (sometimes multiple) spaces saved in the database, and in the interest of finding them amidst the many thousands of other rows, I'm trying to do a query like:
SELECT * FROM `mytable` WHERE `dirtyfield` REGEXP ' $'
But that returns zero rows. I tried a few other variations with other results:
SELECT * FROM `mytable` WHERE `dirtyfield` REGEXP '[[:space:]]$' -- Zero Rows
SELECT * FROM `mytable` WHERE `dirtyfield` REGEXP '[[.space.]]$' -- Zero Rows
SELECT * FROM `mytable` WHERE `dirtyfield` REGEXP '[[.space.]]' -- Those with a space anywhere in the value
SELECT * FROM `mytable` WHERE `dirtyfield` REGEXP '[[.space.]]{2}' -- Those with two spaces in a row
Finding all with a single space doesn't help much, since some clean rows have single spaces between words in that field. That last one catches 90% of the dirty rows, but misses those that have just a single space at the end. Is there something wrong with how I'm using the $ symbol to indicate the end of a field?
The MySQL RIGHT() and SUBSTRING() functions seem to strip off whitespace when calculating the end of the field:
SELECT * FROM `mytable` WHERE RIGHT(`dirtyfield`)=" " -- Only returns one row that has " " for that field
SELECT * FROM `mytable` WHERE SUBSTR(`dirtyfield`,-1)=" " -- Only returns one row that has " " for that field
One other try using a comparison didn't work either:
SELECT * FROM `mytable` WHERE TRIM(`dirtyfield`)!=`dirtyfield` -- zero rows returned
The "dirtyfield" field is a VARCHAR(128), if that matters.
EDIT: I'm an idiot; the fields don't end in spaces, then end in multiple spaces followed by a comma (imported from a bad CSV file).
SELECT * FROM `mytable` WHERE RIGHT(`dirtyfield`,1)=','
That query found them. I was looking at the output of the tables in a comma-separated view and didn't notice the commas were doubled-up.

Had a similar problem. The compare you made with trim():
SELECT * FROM `mytable` WHERE TRIM(`dirtyfield`)!=`dirtyfield`
doesnt work, but:
SELECT * FROM mytable where char_length(dirtyfield) > char_length(trim(dirtyfield))
gets the work done and shows you the rows that have spaces both at the start and/or end of the content. The character count works. Quite honestly i don't know why trim() doesn't compare directly on the first query.
Hope this helps. Like your field, this solution is admittedly a bit dirty.

I think this may be correct:
SELECT * FROM `mytable` WHERE `dirtyfield` REGEXP '[[.space.]]+$'
It matches field ending ($) with 1 or more (+) spaces ([[.space.]])
Anyway if you want to do the same thing with LIKE statement is easier with:
... LIKE '% '
as in answer below.

I have not tried this but I think this might work to find entries that ends with a blank space
SELECT * FROM `mytable` WHERE `dirtyfield` LIKE "% "

Hey i was doing something similar and got in this page, Check below query, this might help..
SELECT * FROM `mytable` WHERE `dirtyfield` LIKE "% %"

Have you considered that you actually get rows with spaces in it, but the web browser doesn't render them for you?
The value " two (2 or more spaces) words " looks like "two words" in your browser.
Try a:
WHERE dirtyfield REGEXP '(^[[:space:]]|[[:space:]]{2,}|[[:space:]]$)'
This should fetch all of those rows. Just consider that you might get the right rows, but it doesn't look that way due to browser.

Related

MySQL - need to find records without a period in them

I've been to the regexp page on the MySQL website and am having trouble getting the query right. I have a list of links and I want to find invalid links that do not contain a period. Here's my code that doesn't work:
select * from `links` where (url REGEXP '[^\\.]')
It's returning all rows in the entire database. I just want it to show me the rows where 'url' doesn't contain a period. Thanks for your help!
SELECT c1 FROM t1 WHERE c1 NOT LIKE '%.%'
Your regexp matches anything that contains a character that isn't a period. So if it contains foo.bar, the regexp matches the f and succeeds. You can do:
WHERE url REGEXP '^[^.]*$'
The anchors and repetition operator make this check that every character is not a period. Or you can do:
WHERE LOCATE(url, '.') = 0
BTW, you don't need to escape . when it's inside [] in a regexp.
Using regexp seems like an overkill here. A simple like operator would do the trick:
SELECT * FROM `links` WHERE url NOT LIKE '%.%
EDIT:
Having said that, if you really want to negate regexp, just use not regexp:
SELECT * FROM `links` WHERE url NOT REGEXP '[\\.]';

Query MySQL field for LIKE string

I have a field called 'areasCovered' in a MySQL database, which contains a string list of postcodes.
There are 2 rows that have similar data e.g:
Row 1: 'B*,PO*,WA*'
Row 2: 'BB*, SO*, DE*'
Note - The strings are not in any particular order and could change depending on the user
Now, if I was to use a query like:
SELECT * FROM technicians WHERE areasCovered LIKE '%B*%'
I'd like it to return JUST Row 1. However, it's returning Row 2 aswell, because of the BB* in the string.
How could I prevent it from doing this?
The key to using like in this case is to include delimiters, so you can look for delimited values:
SELECT *
FROM technicians
WHERE concat(', ', areasCovered, ', ') LIKE '%, B*, %'
In MySQL, you can also use find_in_set(), but the space can cause you problems so you need to get rid of it:
SELECT *
FROM technicians
WHERE find_in_set('B', replace(areasCovered, ', ', ',') > 0
Finally, though, you should not be storing these types of lists as strings. You should be storing them in a separate table, a junction table, with one row per technician and per area covered. That makes these types of queries easier to express and they have better performance.
You are searching wild cards at the start as well as end.
You need only at end.
SELECT * FROM technicians WHERE areasCovered LIKE 'B*%'
Reference:
Normally I hate REGEXP. But ho hum:
SELECT * FROM technicians
WHERE concat(",",replace(areasCovered,", ",",")) regexp ',B{1}\\*';
To explain a bit:
Get rid of the pesky space:
select replace("B*,PO*,WA*",", ",",");
Bolt a comma on the front
select concat(",",replace("B*,PO*,WA*",", ",","));
Use a REGEX to match "comma B once followed by an asterix":
select concat(",",replace("B*,PO*,WA*",", ",",")) regexp ',B{1}\\*';
I could not check it on my machine, but it's should work:
SELECT * FROM technicians WHERE areasCovered <> replace(areaCovered,',B*','whatever')
In case the 'B*' does not exist, the areasCovered will be equal to replace(areaCovered,',B*','whatever'), and it will reject that row.
In case the 'B*' exists, the areCovered will NOT be eqaul to replace(areaCovered,',B*','whatever'), and it will accept that row.
You can Do it the way Programming Student suggested
SELECT * FROM technicians WHERE areasCovered LIKE 'B*%'
Or you can also use limit on query
SELECT * FROM technicians WHERE areasCovered LIKE '%B*%' LIMIT 1
%B*% contains % on each side which makes it to return all the rows where value contains B* at any position of the text however your requirement is to find all the rows which contains values starting with B* so following query should do the work.
SELECT * FROM technicians WHERE areasCovered LIKE 'B*%'

MySQL: SELECT * FROM table WHERE field="some text" doesn't work

I am trying to INNER JOIN two tables on a text field, but I can't get it to work.
I've backtracked to see if I can identify where my query is falling down.
I've simplified my query to use only one table, to see if I can select data from it based on a text string.
I can't make it work.
I feel like an idiot.
This is so basic, why isn't it doing it?
select * from `my-table`
where myKey = "some-text-data-that-i-copied-from-the-data-in-the-table";
Returns no rows.
"some-text-data-that-i-copied-from-the-data-in-the-table" is in field myKey. I can see it. It's in the table!!!
[if it makes any difference I am most familiar with using an Access front-end and I am porting my "skills" to MySQL because MySQL is just better really.. this seems like the most run of the mill SELECT statement ever and yet it doesn't do anything!]
EDIT:
IMSoP does this help any...
select * from mymathssowlink
where MyMathsResourceKey = 'KS2-Number-Counting and Place Value-NC3-Negative Numbers 1';
EDIT 2:
Diego Marinelli - thanks - this returns data
select * from mymathssowlink
where MyMathsResourceKey like '%KS2%';
EDIT 3:
This works...
select * from mymathssowlink
where MyMathsResourceKey like '%KS2-Number-Counting and Place Value-NC3-Negative Numbers 1%';
EDIT 4:
But this still doesn't...
select * from mymathssowlink
where MyMathsResourceKey = 'KS2-Number-Counting and Place Value-NC3-Negative Numbers 1';
puzzled
Table:
CREATE TABLE `mymathssowlink` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`ObjectiveID` varchar(13),
`MyMathsResourceKey` varchar(100),
PRIMARY KEY (`ID`),
UNIQUE KEY `idnew_table_UNIQUE` (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
HOW IT GOT FIXED:
okay very weird but I have fixed the simplified problem now! I remember from my Access days that trailing spaces are the bane of matches and it seems the MySQL is a bit fiddly in this regard to. There was no problem with the data as such but the field MyMathsResourceKey was the last bit of data on each line and so not terminated with a comma. Some lines didn't have any data in that column and so were terminated with a comma rather than the MyMathsResourceKey data. I fixed it by adding a third column to my csv into which i uniformly stuck the string "PLACEHOLDER". I matched this to a column called placeholder in the table receiving the data. Now that the active (2nd column) is always terminated with a comma all the data seems to work. I can't help thinking that this is a bit odd and that MySQL data imports really don't want to be behaving like this... now to try an make my JOIN work, which how this all started!
Thanks to all, especially Rahul for the help.
... and the JOIN Works now...
Going by all the edits in your post and comments; what I feel is, there is extra space present in your column value and so you are not getting the data (since it's not matching the exact string).
So either try like
select * from mymathssowlink
where MyMathsResourceKey
like '%KS2-Number-Counting and Place Value-NC3-Negative Numbers 1%';
(OR)
Use a REPLACE() function to remove all spaces in the field value
select * from mymathssowlink
where REPLACE(MyMathsResourceKey, ' ', '')
= 'KS2-Number-Counting and Place Value-NC3-Negative Numbers 1';
You can as well use TRIM() function if you can guarantee that the spaces are present only in left/right extreme of the string.
select * from mymathssowlink
where TRIM(MyMathsResourceKey)
= 'KS2-Number-Counting and Place Value-NC3-Negative Numbers 1';
You can try Select * from table; and if that works then try select * from table where key like '%some_text%'
It could not be a problem with the sintax but with the query itself.

select command in mysql returns an empty row even though the entry exist in table

When I run the below query in phpmyadmin it returs 0 rows even the entry exists on the table
SELECT * FROM `default_companyshare` WHERE `comp_symbol` = "ACEDBL"
Try this in case you have some space-padding in your database:
SELECT * FROM `default_companyshare` WHERE `comp_symbol` like "%ACEDBL%"
You can also try trimming your result:
SELECT * FROM `default_companyshare` WHERE trim(`comp_symbol`) = "ACEDBL"
You clearly have some issue with the string comparison. Start with:
SELECT *
FROM `default_companyshare`
WHERE upper(`comp_symbol`) like '%ACEDBL%';
This will show you all the symbols that contain that string. Then figure out if the problem is leading/trailing spaces, collation conflicts, hidden characters, or something else.

Replacing backslashes in MySQL 5 table seems to work: but how do I double check?

I am trying to replace escaped quotes in a MySQL 5 table field, like this:
\' to '
\" to "
The query I'm using is:
UPDATE myTable SET content = REPLACE(content, '\\\'', '\'');
UPDATE myTable SET content = REPLACE(content, '\\\"', '\"');
Now it seems to work! What makes me wonder though is that it takes just 5 seconds on 70.000 entries in a 250 Megabyte table.
So is there a way to be sure or to double check?
Eddie
I would just query for the thing you replaced to see if it's still there:
SELECT COUNT(1) FROM table WHERE content REGEXP "%\\\'%";