SQLite select query with like condition in reverse - php

I'm trying to write a query in php that will select a row from a database that partially matches a string.
Better explained via an example:
Say my DB has a field called numberString, with value 'abcd'. I want to write a query that, given "123abcd", will return a field of that row of the database.
SELECT mood
FROM USERS
WHERE numberString like '%$giveNumberString'"
$giveNumberString is the functions parameter (i.e. the string that I want to look for)
But I think those two numberString and '%$givenNumberString'" should be like the other way around in order for the query to work as expected. Is there a way to do this?
Ok the table looks like this:
id | username | numberString | mood
-------------------------------------
1 | myUsrNam | abcd | happy
Now I want, given "123abcd", to retrieve the mood of that person. In other words to match 123abcd against abcd.

I'm not sure this is a legal syntax, but let me try a wild guess: have you tried
SELECT mood from users where '$giveNumberString' like '%' || numberString || '%'
?

Related

Search table multiple columns on variable number of parameters

I have a search input box where a user can enter one or more word and the php script should return all the row where all those words are include in any column.
Suppose a table like this:
|car_id|make|model|year|plate|
+----------------------------+
| 1 |Audi|A4 |2010|AAAAA|
| 2 |Audi|A4 |2012|AAAAB|
| 3 |Audi|Q5 |2010|AAAAC|
+----------------------------+
If a user enter "Aud", he get the 3 rows. If it enter "2010 Audi", he get row 1 and 3, and if he enter "Aud q5 2010", he get only row 3.
What I have done.
If the input as only 1 term, i can build a query like
SELECT * FROM car WHERE make LIKE '%term%' OR model like '%term%' OR year like '%term%'
If the user enter 2 terms, I have to create this query instead (even don't consider the plate column)
SELECT * FROM car WHERE
(make LIKE '%term%' AND model LIKE '%term2%')
OR (make LIKE '%term2%' AND model LIKE '%term%')
OR (make LIKE '%term%' AND year LIKE '%term2%')
OR (make LIKE '%term1%' AND year LIKE '%term%')
OR (model LIKE '%term%' AND year LIKE '%term%')
OR (model LIKE '%term2%' AND year LIKE '%term1%')
If a user enter 3 terms, the query get exponentialy more complexe.
I read about MATCH keyword but some column are not text, like year in this exemple.
What is the correct way to do this kind of search? Should I change database schema? Concat all searchable columns into a string and do some regex,
Thank you.
Create an extra column, all. Have it contain the CONCAT_WS(' ', ...) of all the columns you need to search on.
Create a FULLTEXT(all) index on that column.
Construct the query with just one clause:
WHERE MATCH(all) AGAINST("+Audi +q5 +2010" IN BOOLEAN MODE)
Issues:
FULLTEXT has a minimum word length; either change that (alas, it is a global setting) or deal with short "words" differently. If, say, the min word len is 3, then remove th '+' from before 'q5' in the AGAINST string. Otherwise, InnoDB will find no rows.
Similarly deal with "stop words". Or remove the stop list.
Deal with hyphenated, etc, words in some way.
It may help to do ORDER BY MATCH ... LIMIT 20 to (1) give some preference to the oddball cases, and (2) limit the output when the user does not specify enough.
Or you might want to play fair and do ORDER BY RAND() LIMIT 20.
If you are using 5.7 or MariaDB, a "generated" column may be useful.

Mysql Search value used to find row

Is it possible for Mysql to return the search value that it used to find the row?
For example I have a database like this:
ID | FLIPPERID | PHONENUMBERS | POSTERIDS
1 10001 7003158974,8769873453,9085699812 6477741332,34234324234,5734345,34234
I do a query like this. But with hundreds of values:
SELECT * FROM `flipperaccounts`
WHERE `posterids` = 3126764
OR `posterids` = 65139757
OR `phonenumbers` = 6477741332
OR `posterids` = 72345341;
Now I'm wondering if there's a way to know which value triggered the row to showup?
You can do a direct comparison using a case/when/then statement. I've used CONCAT_WS here in the event that there are multiple columns matched, so you can explode(',', $row['matched_column']) for your convenience.
SELECT
ID,FLIPPERID,PHONENUMBERS,POSTERIDS, CONCAT_WS(', ',
CASE WHEN posterids = 3126764 THEN 'posterids_1',
CASE WHEN posterids = 65139757 THEN 'posterids_2',
CASE WHEN phonenumbers = 6477741332 THEN 'phonenumbers',
CASE WHEN posterids = 72345341 THEN 'posterids_3' ) AS matched_column
FROM flipperaccounts
Then when you get the result back your table will be like:
| ID | FLIPPERID | PHONENUMBERS | POSTERIDS | MATCHED_COLUMN |
"1" "10001" "700315894.." "647774..", "posterids_2"
Then you can access it within your loop statement as an index on the row.
if(!empty($row['matched_column'])) {
echo $row['matched_column'];
}
Hopefully this helps.
I do not know of any way to tell what part of a complex WHERE clause caused a SELECTion.
Note that OR is associative (rather than commutative), so more than one of your clauses may cause a hit, and so the order is important to your answer — problem is, the query optimizer knows that OR is associative, and so it may arbitrarily change the order of the OR clauses! For example, if one column has a shorter index, the query optimizer might choose to do that first, or it may choose to do PRIMARY or UNIQUE columns first.
So it seems to me that your question in non-deterministic, without returning an array of OR clauses that "hit."
You could do this by using "SELECT COUNT(*)" for each of the OR clauses, which is fairly non-intensive, if the columns are indexed.
I went with RiggsFolly idea of making a child table. Thanks for the help.

Multiply column with same content, make them count as "one"

About
I have this table in my database holding some information saved with a user id and time.
| CONTENT | USER ID | TIME |
| text | 1 | 1405085592 |
| hello | 2 | 1405085683 |
| hey | 1 | 1405086953 |
This example could be a data dump from my database, now as you can count there is "three" rows. However I only need to know how many users there have some information in my database. Therefor the result I'm really looking for is "two", because only two users have information in the database. User ID 1 is owning both "text"(1) & "hey"(3) where user ID 2 haves "hello"(2).
In short
I want to count how many users (regardless how many rows of information they have) there are inside my database.
** What I tried **
I tried to fetch every single row into an array and then using array_unique to count them together, works fine but I do not see this as a clean and best way to do this.
Then what?
I could use the array_unique and just use count to see how many rows there are, but I'm looking for something more clean. I tried to search for this, but I'm not actually sure what I should search for in term to hit something I'm looking for. After being stuck and though I wanted to learn something new, I wanted to post this problem here.
Note
I hope you guys can help me, I have tried to make it clear what I'm looking for and what I tried. If not please let me know. Sorry if some of the above contains misspelled words, incorrect grammar or is badly explained. I do not speak English daily, but I try my best.
You are looking for the DISTINCT keyword. It returns the count of unique values of a column:
SELECT COUNT(DISTINCT user_id)
FROM your_table
See example on SQL Fiddle.
This query:
SELECT DISTINCT user_id FROM table
will return just one row for every user in the table.

loop splited string in mysql query

have a string($string) and a Column(DOMAIN) in a table like this:
$string="'domain3','domain2,'domain1'";
-----------------
| DOMAIN |
|---------------|
| domain1 |
| domain2 |
|domain1,domain2|
-----------------
And I am trying to create a sql query that return a result if the domain is included in the string. What I found is that I have to split the entries in the column, so I have something like this:
SELECT * FROM TABLE1 WHERE SUBSTRING_INDEX(DOMAIN, ',', 1) IN ('$string')
But this gives me a result only if the first index match, I want to do a kind of loop.
I don't know if my question is clear enough, but to explain the context, I am trying to filter results using checkboxes.
Thanks!
What you get as results is right. You only substring from the 1st index. What you are looking for an explode functionality in mysql.
You can read the comments on this page for a plethora of solutions to the string-splitting problem: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html.

PHP search function to look in pgsql table

I want to make a search function in my website. I want to search for a string in all fields of my table (about 13 columns). If one row contains a field that matches the string (like operator) I want it to be added to result.
Example
|field 1 | field 2 | field 3|
some string test
test some string
one simple string
Now basically if I search for the string "test" I want to have the first two rows.
Is there a wildcard option for WHERE that I could do something :
SELECT * from my.table WHERE * like '%string%';
There is no such syntax in PostgreSQL (or any other DBMS).
As Spudley pointed out using a query like like '%string%' will be quite slow.
If this is something that is needed very often you should definitely look into PostgreSQL's full text search capabilities.

Categories