Select with match and order by date and then relevance? - mysql

Im using the below to select from 3 columns and it works as it should but when I try to add date to order by then I can´t get it right. Its a mysql database.
SELECT *,
MATCH(artikel) AGAINST ("&soktexten&" IN BOOLEAN MODE)* 10 as rel1,
MATCH(ingress) AGAINST ("&soktexten&" IN BOOLEAN MODE) as rel2,
MATCH(texten) AGAINST ("&soktexten&" IN BOOLEAN MODE) as rel3
FROM produkt
WHERE MATCH (artikel, ingress, texten) AGAINST ("&soktexten&" IN BOOLEAN MODE)
ORDER BY (rel1)+(rel2)+(rel3) DESC LIMIT 25;
I have 3 rows where the "artikel" has the following text and then the date .
Row 1 - "Träbord" - "2019-01-01"
Row 2 - "Träbord aaa" - "2019-01-02"
Row 3 - "Träbord bbb" - "2019-01-03"
I want it to search for the latest date where the matching word is in "artikel".
So if I search for "Träbord bbb" or "Träbord aaa" it is showing them on top of the list as they should, but if I search for only "Träbord" it is showing "Träbord" as the first one in the list and I want it to search for the latest date first, then the matching word.
So how do I change ORDER BY (rel1)+(rel2)+(rel3) DESC LIMIT 25 so it order by date first and then by the matching word?
I have tested with several variants of ORDER BY (rel1)+(rel2)+(rel3), date DESC LIMIT 25 etc but I can´t get it right.
Any input really appreciated, thanks.

I think this does what you want:
ORDER BY (rel1 + rel2 + rel3) > 0 DESC, -- put matches first
date DESC

Related

Grouping mysql by a regex?

I am trying to find the count of how many times a location is used in my table of search results, but I want to group together cases where the same post code area start is used. The following groups purely on the text used:
SELECT count(*),
search_browse_log.postcode_start
FROM search_browse_log
GROUP BY postcode_start
ORDER BY count(*) DESC
But in the data, I have for example CR0, CR1, CR2 (postcode starts). I want to group them all together so I have a count of 3 for "CR", rather than 1 each of CR0, CR1 and CR2.
Thanks in advance if you can help!
Use a conditional in the GROUP BY clause to get either 1 or 2 characters, depending on whether the postcode starts with 1 or 2 letters.
GROUP BY IF(postcode_start REGEXP '^[A-Z][A-Z]',
LEFT(postcode_start, 2),
LEFT(postcode_start, 1))
If it's only the first 2 characters of the postcode, you could use the LEFT function in the group by:
SELECT count(*),
LEFT(postcode_start,2) as `postcode_start`
FROM search_browse_log
GROUP BY LEFT(postcode_start,2)
ORDER BY count() DESC
To group by the non-numeric characters at the start of the string:
SELECT count(*),
IF(postcode_start REGEX '^[a-ZA-Z][0-9]',LEFT(postcode_start,1),LEFT(postcode_start,2)) as `postcode_start`
FROM search_browse_log
GROUP BY IF(postcode_start REGEX '^[a-ZA-Z][0-9]',LEFT(postcode_start,1),LEFT(postcode_start,2))
ORDER BY count() DESC
For reference, see https://dev.mysql.com/doc/refman/5.7/en/regexp.html#operator_regexp

Sorting MySQL query with non-unique values

I want to create a navigation with next and previous buttons and i want to sort the order by popularly of the post. popularity column is made with views + likes
Post_id | post_popularity
1 | 25
2 | 10
3 | 30
4 | 10
5 | 45
So I try adding the query
//Previous
SELECT * FROM posts WHERE post_live=1 and post_popularity>$post_popularity ORDER BY post_popularity ASC LIMIT 1
//Next
SELECT * FROM posts WHERE post_live=1 and post_popularity<$post_popularity ORDER BY post_popularity DESC LIMIT 1
This seems to loop most of the posts and then i try
//Previous
SELECT * FROM posts WHERE post_live=1 and (post_popularity > $post_popularity) OR (post_popularity = $post_popularity AND post_id < $post_id) ASC LIMIT 1
//Next
SELECT * FROM posts WHERE post_live=1 and (post_popularity < $post_popularity) OR (post_popularity = $post_popularity AND post_id > $post_id) ASC LIMIT 1
This seems to do the same thing. Looping most of the posts. Any pointers on how to archive this query. I greatly appropriate your help.
I would select the current, the previous and the next post with one query. In this way you have to execute less queries to load all your data needed to display one site.
SELECT * FROM posts WHERE post_live=1 ORDER BY post_popularity ASC LIMIT 3 offset $index_of_current_post_minus_one;
for the first post the $index_of_current_post_minus_one is 0. You get 3 results the first ist the current item the second is next and the third can be ignored. If you hit your next button you increment your counter $index_of_current_post_minus_one becomes 0 (index of the displayed post is 1 but you always substract 1). From now on it becomes straight forward. This first result row ist your previous , the second your current and the third your next. clicking next again the $index_of_current_post_minus_one becomes 1and so on.
In addition you should create an index on your table pre-sorting your posts on their popularity so the rows must not be sorted for every query:
alter table post add index pop_live(post_popularity, post_live);

How to get next set of data on select top

I loaded the result set with top 10 rows as follows.
SELECT * FROM Persons LIMIT 10;
Now how to select next 10 rows.? Like what in google search results can be toggled between search results.
Pardon if question sounds silly because i didn't found any relevant answer on google.
You can give the LIMIT clause a starting point, like this:
SELECT * FROM Persons LIMIT 50, 10;
This would mean the offset is 50 (it skips the first 50 rows), and the next 10 rows are selected. See also in the manual: MySQL SELECT Syntax.
Use OFFSET + LIMIT to do this
SELECT * FROM Persons
ORDER BY somecol
OFFSET 10 LIMIT 10 -- LIMIT 10 OFFSET 10
For Mysql
SELECT * FROM Persons
ORDER BY somecol
LIMIT 10 OFFSET 10 --LIMIT 10,10
Note: Make sure you add Order by to get meaningful results

mysql query - pairs of repeating numbers

I have a database with 2 columns (ex: no_1, no_2) and then 5000 rows of data, numbers are between 1 - 20 , I need to find a pairs of numbers which where repeating the most of the times?
Any help please ?
Something like this maybe:-
SELECT no_1, no_2, COUNT(*) AS numbercount
FROM SomeTable
GROUP BY no_1, no_2
ORDER BY numbercount DESC

MySQL database resultset with values as close to a number "x" as possible

Im trying to get a result set that contains the 10 values that are closest to, in this case, the number 3.
I have a database that has values in a column named rated which can be 1,2,3,4 or 5. What im trying to do is query the database and return the first 10 rows that have the values closest to 3. The values can be above 3 or below 3. I should note that these values in the rated column are floats.
I then need to sort these rows in order so that rows with value of 3 are first and then the row with lowest offset (+/-) from 3.
Is there any SQL query that can return atleast the result set of values closest to 3 ? or am i going to have to return the whole db and sort it myself?
To get the first 10 rows with highest value down i used the statement
SELECT * FROM tabs ORDER BY 5 DESC LIMIT 10";
5 refers to the column rated
Is there some way to modify this to do what i want ?
Thanks
If I understand your problem correctly, this should do the trick:
select *
from tabs
order by abs(`rated` - 3) asc
limit 10
Note that it sorts by the difference in ascending order, so those with a difference of 0 will come first.
SELECT * FROM tabs ORDER BY ABS(3 - Rate) ASC LIMIT 10
If I got right what you need try:
select *
from (
select
case when -(3-rated) > 0 then -(3-rated) else (3-rated) end as distance,
tabs.*
from tabs
) subsel
order by distance
limit 10