$itemList = DB::table('items')
->orderBy('id', 'desc')
->where('item_status', 2)
->where(function($query) use($queryArr)
{
foreach($queryArr as $uID){
$query->whereRaw("tags LIKE '%$uID%'");
}
})->paginate(21);
I have been facing this issue since a long time. Problem when you do a LIKE search is it grabs the data of WOMEN when it's just eg MEN
Mainly because MEN is inside Women
I also tried the following but failed(This sort of grab a word) men without women data
$query->where('tags', 'LIKE', '%'.$uID.'%');
SELECT 'a word a' REGEXP '[[:<:]]word[[:>:]]';
How do i use that Word boundary query in laravel query builder
Tried this and still failed $query->whereRaw("tags LIKE REGEXP '[[:<:]]Men[[:>:]]'");
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'REGEXP '[[:<:]]Men[[:>:]]')' at line 1 (SQL: select count(*) as aggregate from items where item_status = ? and (tags LIKE REGEXP '[[:<:]]Men[[:>:]]')) (Bindings: array ( 0 => 2, ))
I also understand some asked why not just created a proper way of handling these item's category. Well i think for now using Full Text Search is fine for me at most when it come to scaling i will use elastic search. true?
UPDATE
Apologies for not giving an example of tags
Bag,Shoes,Men,Wedges
Bag,Shoes,Men
Men,Shoes,Bag
If values are separated by commas, try to use following
WHERE `tags` REGEXP "(^|,)men(,|$)"
This will require to have comma or end of string around the word men.
Your REGEXP solution is throwing the syntax error because of the extra LIKE keyword. The correct syntax is simply WHERE column REGEXP 'pattern'.
If you find this hard to remember, try using RLIKE instead, which is a synonym for MySQL's REGEXP. There is less chance you will accidentally write WHERE column LIKE RLIKE ... in your query because it is more obviously redundant.
The pattern itself should work fine. Personally, I dislike using those word boundary classes in MySQL; since you know your tags are comma delimited and space padded, [ ,]Man[ ,] would function just as well. The word boundary class breaks at punctuation other than underscores, so you could run into trouble if you have tags that are hyphenated, for instance.
If you want to use multiple word tags with spaces, either of the previous patterns is buggy. In that case I would try to stick with commas as your delimiter, get rid of the whitespace padding and use anchors instead, as suggested in one of the other answers: (^|,)Man($|,)
In your query you said : Find anything that contains the tag 'MEN' => '%MEN%', that's why it shows: WOMEN AND MEN, so to answer to your question you should use starts with instead of contains, like this :
$query->where('tags', 'LIKE', $uID.'%');
Related
I'm working for the first time with MATCH...AGAINST in php sql but there is one bothering me and I can't figure out how to fix it. This is my code:
SELECT * FROM m_artist WHERE match(artist_name) against('". $_POST['article_content'] ."' IN BOOLEAN MODE)
And this is $_POST['article_content']:
Wildstylez Brothers Yeah Frontliner Waveliner
Now my output should be: Wildstylez, Frontliner and Waveliner cause that's in my database. And I do but besides that I also get the Vodka Brothers, 2 Brothers of Hardstyle and more cause of the word brothers. How do I fix that SQL only selects the literal match?
Full-text search actually is a quite misleading name: you can search the full text by your query (like google does) but it won't guarantee you, that the full text equals your query.
So, according to documentation on Boolean Full-Text Searches your input Wildstylez Brothers Yeah Frontliner Waveliner is interpreted as artist_name contains (at least) one of Wildstylez, Brothers, Yeah, Frontliner and Waveliner as word. This is why you get e.g. the Vodka Brothers, which contains Brothers. For google-like purposes this is just what you want, as you want to get details on something you only know part of as in show me articles on music.
You probably want to use
artist_name LIKE '%name_part1%' OR artist_name LIKE '%name_part2%' ...
or
artist_name IN ('exact_name1', 'exact_name2', ...)
simpliest case would be doing something like
$names = explode(' ', $_POST['article_content']);
$name_searches = array_map(function($a) {return 'artist_name = \''.mysql_real_escape_string($a).'\'';}, $names);
$sql = "SELECT * FROM m_artist WHERE ".implode(" OR ", $name_searches);
but you would loose the ability to find 2 Brothers of Hardstyle as the name itself contains a space.
Another approach can be to prefix all words by '+' and stick to MATCH() AGAINST() and you will find only artists which include every word given.
Please provide more context if this is not what you are looking for.
MySQL query String contains
Hello, I am trying to make an mysql query that looks for a column value that contains a string from a master string I set. So if my master string is '1234567', I would like it to return any results with column values that have '1','2', etc... The above link was as close as to what I can find but I need it comparing in the opposite direction.
eg.:
WHERE '%{$needle}%' LIKE `column`
You are a little vague about where the various values are being stored (your text uses terms like "master string" but the sample code uses different names).
You can do what you want using regexp. Here is an example:
select 'abcd6efg' regexp concat('.*[', '1234567', '].*')
To be honest, regex is different from like in one important respect. regex returns true if any part of the left string matches, whereas for like the entire string has to match. So, the following also works:
select 'abcd6efg' regexp concat('[', '1234567', ']')
I like to put the explicit wildcards in to avoid mistakes when switching between the two.
You can look up the documentation for regular expressions here.
How about
WHERE ? LIKE CONCAT('%', `column`, '%')
where ? is a placeholder having a bound parameter with your master value (1234567) because you are using the PDO or MySQLi extension, right?
You're most certainly not using the deprecated MySQL extension, surely.
I am running MySQL version 5.1.57
I have a HTML form where a user can insert a search-string. I create a $_SESSION on this string, then I run it in a MySQLquery. Something like this:
<?php
$sql = mysql_query ("SELECT
s.student_firstname, s.student_lastname
FROM students s
WHERE (
s.student_firstname LIKE '%$searchstring%' OR
s.student_lastname LIKE '%$searchstring%
)
AND s.isActive = '1' ");
?>
The problem is when a user is searching for multiple words. Then my query fails because it is trying to match the string against the values in either column.
I've read something about MySQL FULLTEXT indexing but as far as I understand, it only works on MyISAM tables(?). How can I be able to search for multiple words using the environment that I have?
I think you should split your searched string on space (" ") and insert each segment in your query, or in another query. For example :
$str = "word1 word2";
With that you search first for the whole string "word1 word2" and after you search in you database for "word1" and "word2".
With this solution you should handle a word ignore list, because words like "a, an, the, or, ..." shouldn't be seek ...
I'm not sure there is an other way with an innoDB table ... The best solution is obviously to use the "match against" command, but it's only available with a full text index under MyISAM.
I am trying to make a search form with php, using the following query :
$this->images('`description`="'.db::escape($mysearch).'"');
It's working great, BUT it returns only the EXACT description that corresponds to $mysearch !
I would like that it returns all the descriptions that contains the keywords (1, 2 or 3) from the $mysearch field.
What is the exact SQL query ? I tried with :
'MATCH `description` AGAINST "'.db::escape($mysearch).'"'
But I get an error back:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'MATCH title AGAINST "mykeyword"' at line 1
The solution was :
'MATCH(title) AGAINST ("'.db::escape($keyword).'" IN BOOLEAN MODE)'
use explode:
http://php.net/manual/en/function.explode.php
on a space or comma as your delimiter, and then do a for each on the resulting array to add a line to the query for each string in that array.
For a pseudo example:
//input of the string
$input = "keyword1 keyword2 keyword3";
$inputArray = explode(" ",$input);
foreach ($inputArray as $keyword) {
$sql .= " OR tableName.ColName like '%$keyword%'";
}
obviously clean it up and validate the input, preferable use prepared statements etc (looks like you are using some sort of ORM?), and hopefully the description column is relatively short and has an index on its full content, otherwise the query will be very slow.
Update: I realize you were attempting the syntax to use a fulltext index. If you have a MyISAM table, or a new enough version of mysql that supports fulltext indexes on InnoDB tables, then you might want to skip this solution I have offered as it WILL become very slow once you have more records in teh table than will fit into memory / cache. Unfortunately, I have never used a fulltext index and cannot help you there. I am switching to using Zend_Search_Lucene vs the solution I listed above. (http://framework.zend.com/manual/en/zend.search.lucene.html)
Table name Styles.
Referenced Column: Style
Coding with PHP 5.
Problem:
My SELECT query to MySQL returns 0 rows.
I'm using the column name in querystring as identifier (something like example.com.php?style=paper-pencils). For SEO purposes I've removed any odd characters and replaced spaces with '-'. Using url rewrite to end up with example.com/paper-pencils.
Working on a database I inherited which uses characters such as '&' or ':' in the Style column. On the database side, the Style column would contain a row with something like "Paper & Pencils" as compared to my slugged version of "paper-pencils".
Things I've Tried:
I de-slug the url so i end up with 'paper pencils' (see below in query example).
I tried
SELECT * ,REPLACE( 'Style', '&', ' ' ) AS Style, REPLACE( 'Style', ':', ' ' ) AS Style FROM Styles
WHERE Style = 'paper pencils'
to no avail. The query I have runs fine, it just comes back with 0 results.
My next step would be to do a PHP SWITCH statement. Something like
case: $_GET['style'] = 'paper-pencils'
$DBstyle = 'Paper & Pencils' but I feel like there has to be some other way around it. I have 30 different possibilities and would prefer something better.
Any suggestions on how I can account for these unusual characters with random occurrences?
Maybe you can add another column to this table called style_slug. This column will contain the slugged version that you use in your urls and will allow you to retrieve the Style column in your query.
Just like Gohn said or, a better one - use an approach which is used on this site - have both an unique identifier and a slug in the url.
example.com/2356356/paper-pencils
will cajole SEO and make your life easy.