I want to search the same field but in multiple values using REGEXP.
Is it possible?
SELECT
*
FROM
posts
WHERE keyword LIKE '%ipad%'
AND keyword LIKE '%iphone%'
AND keyword LIKE '%nokia%' ;
this query is use for OR , i want to convert it to AND condition
SELECT * FROM posts WHERE keyword REGEXP 'ipad|iphone|nokia';
Can your keyword field contain multiple values (devices)? Like ipad;iphone;nokia?
If so, this is bad practice. It violates First Normal Form, and it's a symptom of bad table design. Still, the way you did it with multiple LIKE and AND clauses should work.
Converting this to REGEXP syntax is not easy in MySQL, and definitely not worth the trouble. See this post for more details.
Related
For years when I want my user to search some field in my database where he can type anything he wants I use an algorithm to break the words and search each word separetely... a mess.
For example, if the user types in the search box "aaa bbb ccc" I dont like using:
SELECT id
FROM table
WHERE description LIKE '%aaa bbb ccc%'
Cause sometimes the user types things out of order and the query above wouldng find. What I usually do is breaking the string and concatenating it with PHP so the result becomes:
SELECT id
FROM table
WHERE description LIKE '%aaa%'
AND description LIKE '%bbb%'
AND description LIKE '%ccc%'
But today after talk to a friend I was wondering if there is some native way to do this faster using MY SQL?
What you want to do is called full text search and most relational databases support it nowadays, including mysql.
I think you can use REGEXP. For example:
Select * from table where description REGEXP 'aaa|bbb|ccc'
FULLTEXT Searches are really fast.
INSTR or locate works better than REGEXP. But it depends on various factors.
More comparison here
SELECT * from table where INSTR(description, 'aaa') >0
SELECT * from table where LOCATE(description, 'aaa') >0
My current MySql wild card is LIKE '%A%B%'. This can return values that contain A and B.
Can anyone suggest how can I alter the wildcard statement to return values that contain either A or B.
Thanks in advance.
You can add as many like operator you want within the parenthesis with OR condition like below
select * from tablename where (column_name like '%test%' or same_column_name like '%test1%' or
same_column_name like '%test2%' or same_column_name like '%test3%')
For more info have a look at the below link.
SQL Server using wildcard within IN
Hope that helps you
You can use REGEXP
select * from Table1 where some_column REGEXP '[AB]'
there are lots of different ways in writing this as a regular expression, the above basically means containing A or B.
Generally you want to avoid using REGEXP and LIKE '%something' because the do not use indexes. Thus for large tables these operations would be unusable. When you want to do a search of this kind it's always best to stop and ask: "Have I got the best database design?", "Can I use full text search instead?"
The scenario is this: in a table A, I have one column "tags", which is varchar(255).
In this column I store numbers, separated by commas, like this:
2,14,31,33,56
etc. there can be none, one, or several.
and I need to make a SELECT query that will return rows that have a certain number in this field. right now I'm using this method (don't be alarmed, I know its a poor way.. that's why I'm asking for help!). for example, let's assume the number I want to check is 33. the query is:
SELECT * FROM table_a WHERE
tags LIKE "%,33,%" OR tags LIKE "33,%" OR tags LIKE "%,33" OR tags LIKE "33"
I'm no expert but I know this can't be the method. The first question that comes to mind is: is there a command similar to IN() but that works the other way around?
I mean, can I tell it "find rows where 'tags' contains value 33" ?
When asking this question, I can see that there may be another field type other than varchar(255) to contain this type of data (an array of numbers, after all)
Is there a GOOD and efficient way of doing this? my method works for small tables, yes, but if the table grows.. (say, 10k rows, 50k, 300k ... ) this is obviously a problem.
The function that you want is find_in_set():
SELECT *
FROM table_a
WHERE find_in_set(33, tags) > 0;
You can simplify your like statement to be:
SELECT *
FROM table_a
WHERE concat(',', tags, ',') LIKE '%,33,%';
Neither of these can make use of an index. Having a separate table with one row per entity and per tag is the right way to go (but I think you know this already).
I have a page that gets all rows from a table in a database, then displays the rows in an HTML table.
That works great, but now I want to implement a 'search' feature. There is a searchbox, and search-terms are separated by a space. I am going to make it search three fields for the search terms, 'make' 'model' and 'type.' These three fields are VARCHAR(30).
Currently if I wanted to search using 3 terms (say 'cool' 'abc' and '123') my query would look something like this.
SELECT * FROM table WHERE make LIKE '%cool%' OR make LIKE '%abc%' OR make LIKE '%123%' OR model LIKE '%cool%' OR model LIKE '%abc%' OR model LIKE '%123%' OR type LIKE '%cool%' OR type LIKE '%abc%' OR type LIKE '%123%'
That looks really bad, and it will get even worse if there are more search terms or more fields to search.
My question to you: is there a better way to search? If so, what?
Use REGEXP instead of like
SELECT * FROM table WHERE make REGEXP 'cool|abc|123' OR model REGEXP 'cool|abc|123' OR type REGEXP 'cool|abc|123';
read more about REGEXP
http://dev.mysql.com/doc/refman/5.1/en/regexp.html
http://www.go4expert.com/forums/showthread.php?t=2337
You should use FULLTEXT. Search SO about it, it is very easy and useful.
You could use a JQuery Table Plugin, like data tables Features on-the-fly filtering which you could use instead of a lengthy sql command. And its free.
For some reason, the developers at a new company I'm working for decided to name their columns "ignore" and "exists". Now when I run MySQL queries with those words in the where clause, I get a syntax error; however, I can't seem to figure out how to reference those columns without running into an error. I tried setting them as strings, but that doesn't make any sense.
Help?
Also, is there a term for this kind of mismatch?
put the names in backticks:
`ignore`, `exists`
If you're working across multiple tables or databases you need to escape the database name, table name, and field name separately (if each matches a keyword):
SELECT * FROM `db1`.`table1`
LEFT JOIN `db2`.`table2` on `db1`.`table1`.`field1`=`db2`.`table2`.`field2`
Only the portions that actually match a keyword have to be escaped, so things like:
select * from `db1`.table
are ok too.
The official term is "idiocy" :-) You can put backticks around the names such as
`ignore`
but I would give serious consideration to changing the names if possible. Backticks are not standard SQL, and I prefer my column names to be a little more expressive. For example, ignoreThisUser or orderExists (the general rule I try to follow is to have a noun and a verb in there somewhere).
Interestingly, some DBMS' can figure out not to treat it as a reserved word based on context. For example, DB2/z allows the rather hideous:
> CREATE TABLE SELECT ( SELECT VARCHAR(10) );
> INSERT INTO SELECT VALUES ('HELLO');
> SELECT SELECT FROM SELECT;
SELECT
---------+---------+---------+--------
HELLO
DSNE610I NUMBER OF ROWS DISPLAYED IS 1