I have this scenario:
I want to check for particular words, and if they match a term, I will have to update the content of that page and link it to the term. But for now I am focusing on getting the content pages which have a part of the content the same as a particular term.
This is an idea of what I need to do, but it is not working since the subquery returns more than one field.
I want to find WHERE m.module_content is LIKE any of the terms I have, but it should check with them all.
SELECT m.module_termid, t.term_name, m.module_name, m.module_content
FROM modules m
JOIN terms t ON m.module_termid = t.term_id
WHERE m.module_content LIKE '%' || (SELECT term_name FROM terms) || '%'
module_content has text in html format, so eventually all I would need to do is, if it matches a term and it is not yet links, I will add a link to that particular term.
What is the best option to do here? (I am using mysql btw)
To give you an example of what the expected result is:
Terms: id: 1, name: hello Modules: id: 1, content: < p > Hello World < /p >
I would like that modules with id 1 is brought up, since it contains content which somewhere has the term name "hello"
Updated:
Tried Pablo's solution but this is what happens:
"Ray Davis" has nothing to do with the term "Float" for example, so that should not have appeared.
I think you just need to change your JOIN condition to something like:
SELECT m.module_termid, t.term_name, m.module_name, m.module_content
FROM modules m
JOIN terms t ON (m.module_content LIKE '%' || t.term_name || '%')
Having said that, this could be potentially very inefficient. Consider using a FULL TEXT INDEX INSTEAD for this operation.
After a bit of research, my solution would look like this:
SELECT m.module_termid, t.term_name, m.module_name, m.module_content
FROM modules m
INNER JOIN terms t ON m.module_termid = t.term_id
WHERE m.module_content LIKE CONCAT('%', TRIM(t.term_name), '%')
edit: Regarding Paul Morgans comment, I replaced CONCAT('%', t.term_name, '%') with CONCAT('%', TRIM(t.term_name), '%') so that all the whitespaces in t.term_name are stripped off. If you need the whitespaces in t.term_name, just remove the TRIM call and use the old version (CONCAT('%', t.term_name, '%'))
MySQL does not have any concatenation operator, and the query should actually be written as:
SELECT m.module_termid, t.term_name, m.module_name, m.module_content
FROM modules m
JOIN terms t ON m.module_content LIKE CONCAT('%', t.term_name, '%');
But what happened:
m.module_content LIKE '%' || t.term_name || '%'
is actually equivalent to
(m.module_content LIKE '%') || (t.term_name) || ('%')
which is always 1. Thus, you have a Cartesian Product =)
UPD: more as a reference to myself, MySQL does have a concatenation operator ||, but to use it one should set PIPES_AS_CONCAT mode:
mysql> SET sql_mode= 'pipes_as_concat';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT 'qwe' || 'asd';
+----------------+
| 'qwe' || 'asd' |
+----------------+
| qweasd |
+----------------+
1 row in set (0.00 sec)
You may try this instead:
SELECT m.module_termid, t.term_name, m.module_name, m.module_content
FROM modules m
JOIN terms t ON (m.module_content LIKE '%' + t.term_name + '%')
Instead of "LIKE", using "IN" should be the solution: something like:-
SELECT m.module_termid, t.term_name, m.module_name, m.module_content
FROM modules m JOIN terms t ON m.module_termid = t.term_id
WHERE m.module_content IN (SELECT term_name FROM terms);
Try the below query -
SELECT
tp.module_termid,
tp.term_name,
tp.module_name,
tp.module_content
FROM (
SELECT
m.module_termid,
t.term_name,
m.module_name,
m.module_content,
IF(LOCATE(t.term_name,m.module_content)!=0, m.module_content, ' ')
as required_content
FROM modules m
LEFT JOIN terms t ON m.module_termid = t.term_id
) tp
WHERE tp.required_content != '';
For the above query you will get all rows where term_name columns data is present as a whole word in modules table's module_content column. If you dont want to match only on whole word then in that case u can use MYSQL'S regular expression function in place of LOCATE function.
The documentation for LOCATE function can be found out here
I don't think it is a good way to resolve the problem like this.supports that you have a lot of module items,and the popular word is limit.each time you exec the sql,it needs lots of disk io and may block the online mysql db.
my way is like this:
invert index the module content.
search the popular words with the index.
bind the module id to the key word.
as you can see.it is very efficient and fast.so,the problem is how to make inverted index on the module content.sphinx will do a good job.
hope this will help you:)
Related
I need to get the data from a table where the row values are comma-separated strings, like this: 5,10,16,25,7 I'm also using a LEFT JOIN, so I need something like this:
// ...
SELECT ... s.`other_thing`
LEFT JOIN `something` s
ON w.`whatever` = REGEXP CONCAT('(,|^)', s.`id`, '(,|$)')
// ...
I need to get something like this: (,|^)5(,|$) on ON
EDIT: I solved this with a simple LIKE CONCAT('%', s.id, '%')
EDIT 2: If you want to concat the Regex, you can use: REGEXP CONCAT('(^|,)(',s.id,')(,|$)')
I strongly discourage this data model. Your next question is likely to be about performance -- and there is really no hope. You should have a junction/association table for the lists, rather than storing multiple values in a string.
Sometimes, we are stuck with other people's really, really, really bad design decisions. If this is the case, MySQL has a function to help:
SELECT ... s.`other_thing`
FROM x LEFT JOIN
something s
ON find_in_set(s.id, x.really_bad_list_format) > -
I have two tables and I am trying to JOIN them and use the LIKE function on mySQL.
My initial code was :
select A.column
from A
join B
on (B.column) like ('%A.column%');
then I searched stackoverflow past answers and I found that my version was not wrong and at the same time I found this version which did not work either:
select A.column
from A
join B
on B.column like '%'+ A.column +'%';
In the end I used this one :
select A.CPM , B.column , A.column
from A
join B
on B.column like concat('%', A.column,'%');
and it worked. My question is why didn't the previous versions work? Is it because of mySQL version? From my research the syntax is correct in all 3 versions. The results on mySQL for the first two were blank though.
First: Won't work
select A.column
from A
join B
on (B.column) like ('%A.column%');
Reason:
This is just string literal, hardcoded value
B.column LIKE '%A.column%'
Second: Won't work
select A.column
from A
join B
on B.column like '%'+ A.column +'%';
Reason:
+ is not for string concatenation but for addition. Example:
SELECT '%' + 'a' + '%' -- result 0, mysql tries to convert to numbers and compute sum.
Third: Will work
select A.CPM , B.column , A.column
from A
join B
on B.column like concat('%', A.column,'%');
Reason:
You build last value at runtime using correct function CONCAT
In MYSQL Like is a string comparison function.
LIKE operator is used to search for a specified pattern in a column not column matching.
In above two example you are matching with column. In last one you first convert column into string and then apply like.
I have created a subquery that searches for a particular string from one table, using the SQL LIKE condition. I would like to use this subquery's result as the string to search for in my main SQL query also using the LIKE condition. I tried the below code but I get syntax errors, although it seems to be the way it should be done...sadly I am not an SQL expert and just trying to feel this out.
SELECT * FROM `allcesseries`
WHERE series_id LIKE '%'+(SELECT industry_code FROM `ceindustry` WHERE industry_name LIKE '%Technical and trade schools%')+'%'
SELECT * FROM `allcesseries`
WHERE series_id LIKE concat('%',
(SELECT industry_code FROM `ceindustry`
WHERE industry_name LIKE '%Technical and trade schools%'),
'%')
I would suggest that you use exists in this case:
SELECT *
FROM `allcesseries` a
WHERE EXISTS (SELECT 1
FROM `ceindustry` c
WHERE c.industry_name LIKE '%Technical and trade schools%' AND
a.series_id LIKE CONCAT('%', c.industry_code, '%')
);
If you have multiple matches, then this will work as expected.
You can also phrase this directly as a join, if you want:
SELECT a.*
FROM `allcesseries` a JOIN
ceindustry c
ON c.industry_name LIKE '%Technical and trade schools%' AND
a.series_id LIKE CONCAT('%', c.industry_code, '%')
But if there are multiple rows that satisfy the conditions in ceindustry, you will get duplicates.
I do have two tables.
Classifieds, containing a body text.
Keywords, containing keyword combinations like "silver ring"
Now I am trying to find out, how many exact matches are inside the text field for each keyword.
e.g:
chihuahua bilder 30
chihuahua charakter 230
Somehow my SQL-Statement is missing something:
SELECT k.keyword, count(*) AS c
FROM `classifieds` c, keywords k
WHERE c.text LIKE concat('%', + k.keyword + '%')
GROUP BY keyword
The count value is always the same for each keyword.
Does somebody have an idea where the error is? Thank you for any help.
Here is tricky sql:
SELECT text, keyword,
(LENGTH(c.text) - LENGTH(REPLACE(c.text, k.keyword, ''))) / LENGTH(k.keyword)
FROM classified c INNER JOIN keywords k
ON c.text LIKE CONCAT('%', k.keyword, '%');
Let $replace = REPLACE(c.text, k.keyword, '')
This remove keyword from text
Let $len = LENGTH(c.text) - LENGTH($replace)
This calculates "how many characters are removed from text"
$len / LENGTH(k.keyword)
Finally we get how many keywords text has.
I'm trying to join two tables based on two values being alike. I have this so far but I'm getting a SQL error as soon as I use the %.
SELECT downloads.d_key, payer_email
FROM paypal_log
INNER JOIN
downloads
ON downloads.d_key LIKE "%" + paypal_log.custom + "%"
The downloads.d_key will be within the paypal_log.custom.
Any help appreciated with this.
Try
SELECT 'one' + 'two' FROM DUAL
and see what you get. You'll want to use
LIKE concat('%', paypal_log.custom, '%')
MySQL concatenation operator is ||. You can also use the CONCAT() function:
SELECT downloads.d_key, payer_email
FROM paypal_log
INNER JOIN
downloads
ON downloads.d_key LIKE '%' || paypal_log.custom || '%' ;
As others pointed, you are probably doing something very, very wrong.