mysql find best matching word in one row - php

i have following table:
------------------------
| uid | attrvalue |
------------------------
| 1 | Spray |
| 2 | strong |
| 3 | very strong |
| 999 | Creme |
------------------------
now i have a query in php and like to find all rows where all queries are found.
SELECT * FROM attrtable WHERE MATCH (attrvalue) AGAINST ('Spray+very+strong' IN BOOLEAN MODE);
I like that it only finds row 1 and 3. But the resultrows are 1, 2 and 3.
So its important that it founds all words or word combinations in the table rows. The query doesn't contain words or combined words which aren't in the table (I check this first).

Just use LIKE, but the other way around to what your probably used to.
select query
from table1
where 'attrvalue' like concat(query,'%')
order by length(query) desc
limit 1

Related

Get Matching MySQL Rows from List?

I've got a list of ID numbers, (ex: 100230, 123890, 342098...). I've also got a table, with one column devoted to ID numbers:
thisID | name | dateBirth | State
----------------------------------
192465 | Fred | 94-12-06 | OR
197586 | Alex | 78-04-26 | NM
197586 | Alex | 78-04-26 | CA
178546 | Sam | 65-12-01 | NY
112354 | Katy | 89-06-22 | CO
...
I need to return any rows with 'thisID' that matches any of the items in the list I've got. Also, note that sometimes there may be multiple rows with the same ID that match an item in the list... in that case, all matching records should be returned.
I've looked around, and seen some recommendations to use arrays or temporary tables or something, but nothing definitive. How should I do this?
You can use the IN sql syntax for this, if I understand you correctly.
SELECT * FROM tablename
WHERE thisID IN (100230, 123890, 342098);
You can do like this:
select * from [table_name] where thisID in ([your IDs]);
It will return all the rows that match the given IDs.
See the SQLFiddle Demo

mysql show offset with query

I have some data in my database
---------
| Name | Offset(only for imagine it)
---------
| Aa | 1
| Ab | 2
| Ba | 3
| Cf | 4
| As | 5
---------
when use this query
SELECT * FROM table LIMIT 1,3;
it must be show 3 of the first data, Aa, Ab, Ba, with offset like that.
Now, I want to selecting all of Name with prefix a, so use this query
SELECT * FROM table WHERE Name LIKE 'a%' LIMIT 1,3;
I want to show the result of that query with the offset, how to do this?
Loop it is not the solution I needed.
---------
| Name | Offset(only for imagine it)
---------
| Aa | 1
| Ab | 2
| As | 5
---------
Any help appreciated
Thank you!
You have it mostly correct. However, rows start at 0. So the answer: SELECT * FROM table WHERE Name LIKE 'a%' LIMIT 0,3
That SQL query will select everything in the table table that starts with the letter 'a' (or 'A').
For alphabetical order, use ORDER BY Name.

How to match the comma separated values in mysql and get the values

My table User
+----+-----------+---------+--------+---------+------+-------+
| id | name | email | number | call_no | chek | Extra |
+----+-----------+-------+----------+---------+------+-------+
| 1 | one | a#a.com | 123 | 1164 | 1 | 1,2 |
+----+-----------+---------+---------+---------+------+------+
| 2 | two | a#a.com | 123 | 1164 | 1 | 2,1 |
+----+-----------+---------+---------+---------+------+------+
I have the field called Extra it contains the value 1,2
what is my question is ?
I need to match the 1,2 in the table id and myresult like one,two from the user table
For simple example query.what im tried is in below ?
select name from user Extra in('1,2');
My expected output is
one,two
If i tried to do in explode and if i run it in loop i can get the result but i need this in sql is it possible to get it?
You should have a separate table with one row per id and each value of extra. This is called a junction table. SQL has a great data structure for storing lists of things, called a table not a string. And, storing numbers as characters is even worse.
You can, however, do what you want with a join and aggregation:
select id, group_concat(e.name) as names
from table t left join
table e
on find_in_set(t.id, e.extra) > 0
group by t.id;

MYSQL: Get next 'n' results

Right now I have a PHP script that is fetching the first three results from a MYSQL database using:
SELECT * FROM table Order by DATE DESC LIMIT 3;
After that command I wanted PHP to fetch the next three results, initially I was going to use:
SELECT * FROM table Order by DATE DESC LIMIT 3,3;
However there will be a delay between the two commands which means that it is very possible that a new row will be inserted into the table during the delay. My first thought was to store the DATE value of the last result and then include a WHERE DATE > $stored_date but if entry 3 and 4 have the same date it will skip entry 4 and return results from 5 onward. This could be avoided using the primary key field which is an integer which increments automatically.
I am not sure which the best approach is, but I feel like there should be a more elegant and robust solution to this problem, however I am struggling to think of it.
Example table:
-------------------------------------------
| PrimaryKey | Data | Date |
-------------------------------------------
| 0 | abc | 2014-06-17 11:43:00 |
| 1 | def | 2014-06-17 12:43:00 |
| 2 | ghi | 2014-06-17 13:43:00 |
| 3 | jkl | 2014-06-17 13:56:00 |
| 4 | mno | 2014-06-17 14:23:00 |
| 5 | pqr | 2014-06-17 14:43:00 |
| 6 | stu | 2014-06-17 15:43:00 |
-------------------------------------------
Where Data is the column that I want.
Best will be using primary key and select like
SELECT * FROM table WHERE pk < $stored_pk Order by DATE DESC LIMIT 3;
And if you have automatically generated PK you should use ORDER BY pk it will be faster
Two options I can think of depending on what your script does:
You could either use transactions: performing these queries inside a transaction will give you a consistent view of the data.
Alternatively you could just use:
SELECT * FROM table Order by DATE DESC;
And only fetch the results as you need them.

Does ORDER BY apply before or after DISTINCT?

In a MySQL query, when using the DISTINCT option, does ORDER BY apply after the duplicates are removed? If not, is there any way to make it do so? I think it's causing some issues with my code.
EDIT:
Here's some more information about what's causing my problem. I understand that, at first glance, this order would not be important, since I am dealing with duplicate rows. However, this is not entirely the case, since I am using an INNER JOIN to sort the rows.
Say I have a table of forum threads, containing this data:
+----+--------+-------------+
| id | userid | title |
+----+--------+-------------+
| 1 | 1 | Information |
| 2 | 1 | FAQ |
| 3 | 2 | Support |
+----+--------+-------------+
I also have a set of posts in another table like this:
+----+----------+--------+---------+
| id | threadid | userid | content |
+----+----------+--------+---------+
| 1 | 1 | 1 | Lorem |
| 2 | 1 | 2 | Ipsum |
| 3 | 2 | 2 | Test |
| 4 | 3 | 1 | Foo |
| 5 | 2 | 3 | Bar |
| 6 | 3 | 5 | Bob |
| 7 | 1 | 2 | Joe |
+----+----------+--------+---------+
I am using the following MySQL query to get all threads, then sort them based on the latest post (assuming that posts with higher ids are more recent:
SELECT t.*
FROM Threads t
INNER JOIN Posts p ON t.id = p.threadid
ORDER BY p.id DESC
This works, and generates something like this:
+----+--------+-------------+
| id | userid | title |
+----+--------+-------------+
| 1 | 1 | Information |
| 3 | 2 | Support |
| 2 | 1 | FAQ |
| 3 | 2 | Support |
| 2 | 1 | FAQ |
| 1 | 1 | Information |
| 1 | 1 | Information |
+----+--------+-------------+
However, as you can see, the information is correct, but there are duplicate rows. I'd like to remove such duplicates, so I used SELECT DISTINCT instead. However, this yielded the following:
+----+--------+-------------+
| id | userid | title |
+----+--------+-------------+
| 3 | 2 | Support |
| 2 | 1 | FAQ |
| 1 | 1 | Information |
+----+--------+-------------+
This is obviously wrong, since the "Information" thread should be on top. It would seem that using DISTINCT causes the duplicates to be removed from the top to the bottom, so only the final rows are left. This causes some issues in the sorting.
Is this the case, or am I analyzing things incorrectly?
Two things to understand:
Generally speaking, resultsets are unordered unless you specify an ORDER BY clause; to the extent that you specify a non-strict order (i.e. ORDER BY over non-unique columns), the order in which records that are equal under that ordering appear within the resultset is undefined.
I suspect you may be specifying such a non-strict order, which is the root of your problems: ensure that your ordering is strict by specifying ORDER BY over a set of columns that is sufficient to uniquely identify each record for which you care about its final position in the resultset.
DISTINCT may use GROUP BY, which causes the results to be ordered by the grouped columns; that is, SELECT DISTINCT a, b, c FROM t will produce a resultset that appears as though ORDER BY a, b, c has been applied. Again, specifying a sufficiently strict order to meet your needs will override this effect.
Following your update, bearing in mind my point #2 above, it is clear that the effect of grouping the results to achieve DISTINCT makes it impossible to then order by the non-grouped column p.id; instead, you want:
SELECT t.*
FROM Threads t INNER JOIN Posts p ON t.id = p.threadid
GROUP BY t.id
ORDER BY MAX(p.id) DESC
DISTINCT informs MySQL how to build a rowset for you, ORDER BY gives a hint how this rowset should by presented. So the answer is: DISTINCT first, ORDER BY last.
The order in which DISTINCT and ORDER BY are applied, in most cases, will not affect the final output.
However, if you also use GROUP BY, this will affect the final output. In this case, the ORDER BY is performed after the GROUP BY, which will return unexpected results (assuming you expect the sort to be performed before the grouping).

Categories