I have a query in mySQL that's meant to return search terms that are used on our site. Yes, this is for a tag cloud, and yes, I know it's a mullet :)
We've got an admin page where administrators can view search terms and choose to exclude them from showing up in the cloud. These words go into the "badWords" table. We've gotten some terms like "foo%2525252525252520bar", and we're having trouble getting those excluded.
In pseudocode, the query to get the search terms for the cloud is:
SELECT * FROM `searchTerms` WHERE `word` NOT IN ( SELECT `word` FROM `badWords` )
This works fine, unless one of the terms returned from the subquery has a % in it. Is there a way to escape the entire subquery? I've tried doing a
replace( SELECT `word` FROM `badWords`, '%', '\%' )
... but that's apparently not syntactically correct.
I can do two queries if need be, but wondered if there's a way to get it done as is.
Thanks!
==============================
UPDATE: closing this for now, as I think the error lies elsewhere. Will report back once I know for sure, but don't want folks wasting time answering the question here if it's not the correct question...
Upvoted both of the replies received so far. Thanks, guys.
==============================
UPDATE 2: sigh Nevermind... can't close it :\
==============================
FINAL UPDATE: Well, looks like escaping the value isn't the problem. The admin page passes the value in the URL before it's added to the badWords table. In passing the value via the URL, it changes. So what's added to badWords is actually "foo%25252525252520bar" (there's one less "25" sequence). If I manually update the value in badWords and add back the missing "25" it works as expected. So no need to replace or escape anything. I just need to fix those URL values properly.
==============================
I don't think the % is your problem here. I think that you're trying to use REPLACE() on the subquery itself (SELECT ...), and not on a column value (word). Try this instead:
SELECT * FROM `searchTerms`
WHERE `word` NOT IN (
SELECT REPLACE(`word`, '%', '\%') AS word FROM `badWords`
);
Good luck!
I'm not very good with MySQL syntax, but SQL Server let's you do it this way:
SELECT * FROM `searchTerms` WHERE `word` NOT IN ( SELECT REPLACE(`word`, '%', '\%') FROM `badWords` )
NOTE: Basically all I did was move your REPLACE over some =) Hope this helps.
Related
My Situation:
I have url's in a field containing blog posts. The url's are being stored in my database with escape characters. My task at the moment is to replace some already inserted 'http' url's with 'https' url's, but REPLACE will match neither the original url nor the escaped url. I can't just replace every instance of 'http:', because I only want to affect certain links in each post, not every link.
I am very familiar with SQL, as well as REPLACE, so I'm not just asking how REPLACE works and how to use it. Another user here has tested my queries in his environment and they work. So, there must be something in my configuration that is preventing the queries from functioning as expected.
I have searched this site and google extensively for several hours and have found nothing specifically addressing my issue. Everything I have tried is included below and if there is something else I should try, I don't know what that is and I haven't found any suggestions/posts/comments that suggest doing anything differently.
Example URL:
http://test01.mysite.com
As Stored in DB:
http:\/\/test01.mysite.com
Code to Re-Create Situation:
DROP TABLE IF EXISTS test_posts;
CREATE TABLE IF NOT EXISTS test_posts (
id int NOT NULL AUTO_INCREMENT,
post_content longtext NOT NULL,
PRIMARY KEY (id)
)
INSERT INTO
test_posts
(post_content)
VALUES
('content content content Link I want to change content content content Link I don\'t want to change content content content Link I want to change content content content Link I don\'t want to change');
If I run
UPDATE
test_posts
SET
post_content = REPLACE(post_content, 'http://test01.mysite.com', 'https://test01.mysite.com');
or
UPDATE
test_posts
SET
post_content = REPLACE(post_content, 'http:\/\/test01.mysite.com', 'https://test01.mysite.com');
zero records are affected.
For testing purposes, I ran the following query which returns 0 rows.
SELECT
*
FROM
test_posts
WHERE
post_content LIKE '%http://test01.mysite.com%'
OR
post_content LIKE '%http:\/\/test01.mysite.com%'
OR
post_content LIKE '%http:\\/\\/test01.mysite.com%'
OR
post_content LIKE 'http:%/%/test01.mysite.com%';
If I run:
SELECT
*
FROM
test_posts
WHERE
post_content LIKE '%http:_/_/test01.mysite.com%'
It does return matches, but that doesn't solve the real problem of how to match when using UPDATE/REPLACE.
I have tried on two different servers and I get the same results on both.
I have tried the following Engine/Collation combinations and all return the same 0 records results:
MyISAM/latin1_swedish_ci
MyISAM/utf8mb4_unicode_ci
InnoDB/latin1_swedish_ci
InnoDB/utf8mb4_unicode_ci
Anybody know how I can write these queries so that REPLACE will find matches to those url's or what settings in my database or PhpMyAdmin may be causing the queries to return/affect 0 rows?
I think the backslash must be escaped in MySQL
field_name LIKE 'http:\\/\\/test01.mysite.com%'
Of course one could go for sure and use the single char wildcard __
field_name LIKE 'http:_/_/test01.mysite.com%'
or for your both cases: an optional backslash:
field_name LIKE 'http:%/%/test01.mysite.com%'
I'm still baffled as to why the queries with LIKE won't work, but, sadly, using those to narrow down the problem clouded my judgement and I didn't try all the same combinations in the REPLACE functions.
The following works:
UPDATE
test_posts
SET
post_content = REPLACE(post_content, 'http:\\/\\/test01.mysite.com', 'https://test01.mysite.com');
If anyone can explain to me why these combinations work with REPLACE, but not with LIKE, I'd really love to know. Thanks!
There is no reason, your query won't work if you have run properly, there is something else, you may be missing here.
UPDATE
test1
SET
name_1 = REPLACE(name_1, 'http:\/\/test01.mysite.com', 'https://test01.mysite.com')
works well and does the job of repalcing the \/ with /.
See screen-shot attached,
You may have some other problem, please check and update the question, if so.
Edit after comments
If you have more data points in URL, change query like below.
UPDATE
test1
SET
name_1 = REPLACE(name_1, '\/', '/')
Above will replace all the occurrence of \/ with /.
As \\ did not work to represent/escape a backslash, use regular expression functions:
REGEXP_LIKE('.*http:\\/\\/test01\.mysite.com.*')
REGEXP_REPLACE(field, 'http:\\/\\/', 'http://')
Here \\ should work.
I'm having issue with my study project for creating database in MySQL.
I've imported data using LOAD to my created table from a CSV file. Now when I'm executing select * from mytable everything show up perfectly, but when I execute select * from bi_jogging.routes as r where r.Creator_Email="jhenderson7c#bbb.org"
I get nothing.
The email is there, I've tried different syntax options but it seems to be something else, I suspect something with the varchar format, I really have nothing in mind.
For other tables it works fine and others not.
You can try using the query:
select * from bi_jogging.routes as r where r.Creator_Email like "%jhenderson7c#bbb.org%"
If like operator shows the result then there may be white spaces in the email, please double check..
For join try this:
select * from bi_jogging.routes as r join bi_jogging.buddies as b
on b.Email like '%r.Creator_Email%'
I think it should work. Again check with same code.
select * from bi_jogging.routes as r where r.Creator_Email='jhenderson7c#bbb.org'
if [select * from mytable] this works ,then try to copy the email from result and paste it in where clause.
There may be conflicts between quotes.
your table entry contains quotes???
check properly. i think you have quotes in your table entry,so when you try this,
select * from bi_jogging.routes as r where r.Creator_Email like "%jhenderson7c#bbb.org%"
'%' sign matches with any character and you will get the result.
Inside the tablejhenderson7c#bbb.org and "jhenderson7c#bbb.org" are completely different.
I found spaces in the mysql tables after few emails, so I guess that was it. burned 8 hours on this one, thank you all. I could not find the spaces at the end of the mail by looking at it, I had to hit backspace to see that only after two hits the last char is deleted
this helped me : UPDATE bi_jogging.results set Mail_Found = TRIM(Replace(Replace(Replace(Mail_Found,'\t',''),'\n',''),'\r',''));
I have the following query:
INSERT INTO insertlog (Inforamtion) VALUES (
concat("Row Was Inserted",curdate());
MySQL is returning an error, but I cannot figure out why. My google searches do not show examples on how to perform something like this.
use it simpler like that
INSERT INTO insertlog (Inforamtion)
SELECT concat("Row Was Inserted ",curdate()) ;
be sure if your column is Information or Inforamtion
your query also works but you missed ) in the end . here demo with both solutions :
Demo to try here
I think you are missing one closing )
Moreover as Bill pointed, you may have spelled your column name incorrectly - information
I am having issues with my MySQL syntax. I would like to run a select query where either one of two options are true. However the following code does not work.
SELECT * FROM games WHERE genre="indie" OR title="indie"
I have been fooling around and look at other threads and have found out how to use OR to check the same column for multiple entries but not a way to check different columns for the same entries. When I do:
SELECT * FROM games WHERE genre="indie"
The query works fine. Any help would be greatly appreciated.
The only way I see this really would't work, is if you've mistyped the name of the column 'title' (if the second query you wrote works)
The assumptions about the case sensitivity are wrong, since the second query returns something, the first should return at least the same rows as the second one
In MySQL " " works just as ' ', so this assuption was wrong too.
If you post more information, it would be easier to help you
Maybe you ignoring the upper/lower case? Also use like
You can use this:
SELECT * FROM games WHERE (LOWER(genre) like 'indie') OR (LOWER(title) like 'indie')
select count(*) FROM antecedente_delito WHERE rut_polichile = NEW.rut_polichile
this statement is giving de value 0, when it should give me 18 :/ ive been trying a lot to find any bug in it.
Here's the working solution that I mocked up using/changing your code in SqlFiddle. http://sqlfiddle.com/#!2/ac2e9/1
To trouble shoot this, I would view your actual values and verify that NEW. is returning what you think it should. Sometimes it may be doing some trims or removal of special characters, especially the _ and % signs are likely to stripped in subprocedures.
I would start with the query:
select top 50 rut_polichile, NEW.rut_plichile FROM antecedente_delito
If the issue is not obvious from that add in a varbinary check:
select top 50 cast( rut_polichile as varbinary), cast(NEW.rut_plichile as varbinary) from antecedente_delito
If the table only has 18 records, then you should be good to go with the above troubleshooting, but if there is more data, I would suggest limiting your results from the above by the rowid or other identifier in a where statement.
It's not the answer, but I hope it helps you find the answer.
The SELECT privilege for the subject table if references to table columns occur via OLD.col_name or NEW.col_name in the trigger definition.
but in your trigger i can't see any trigger definition. so try without NEW.
for more info: http://www.sqlinfo.net/mysqldocs/v51/triggers.html or
http://bugs.mysql.com/bug.php?id=31068