Sorting MySQL query with non-unique values - mysql

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);

Related

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

selecting the first value that equals a number or letter sql php

I have a db with 6 columns: Taarij, Mispar ,Tiltan, Ale, Yaalom and Lev.
I have a query that brings me the 50 last results ordered by Mispar, that works.
select * from Hagrala order by Mispar desc limit 0,50
I want from that query result to find some data.
For example I want to find the value of the field Mispar where Ale = 7 the first time.
What I mean that 7 can and will appear several times in the column called Ale, but I am looking in which Mispar is the highest.
If in a row Mispar = 30765 and Ale = 7 and in another row Mispar = 30755 and Ale=7 also I want to receive only 30765.
Just use order by and limit:
select *
from Hagrala
where Ale = 7
order by Mispar desc
limit 1;

MySql Select Id <= Maximum value in the table

When using the <= in a MySql statement, is it possible to make MySql select the maximum value in a table without supplying a value to <= in the sql statement?
Eg:
id
----
1
2
3
4
5
6
Eg:
// start from the last record when no value is supplied
select id from table where id <= * ORDER BY id DESC LIMIT 5
Result
6
5
4
3
2
// start from the 5th record when a value is supplied
select id from table where id <= 5 ORDER BY id DESC LIMIT 5
Result
5
4
3
2
1
My problem is, this statement is in a php function, so I cannot change it dynamically. Is it somehow possible to do what I'm trying, or perhaps another way to get around this?
You can use NULL instead of using *
SET #var_search_value = NULL -- OR 5
SELECT id
FROM table
WHERE id <= #var_search_value OR #var_search_value IS NULL
ORDER BY id DESC LIMIT 5
If you want to get every record which is less than or equal to the maximum value in a particular column, then logically you want to get every record:
select id from table ORDER BY id DESC LIMIT 5
No WHERE clause is required.

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

Recordset Iterating

I want to iterate through records returned from a MySQL database using Perl, but only ten records at a time. The reason is that the server component can only handle 10 items per request.
For example:
If the query returned 35 records then
I have to send the data in 4 requests:
Request # # of Records
-------- --------
1 10
2 10
3 10
4 5
What is the best way to accomplish the task?
Look at the LIMIT clause for MySQL. You could have a query like:
SELECT * from some_table LIMIT 0, 10;
SELECT * from some_table LIMIT 10, 10;
etc. where the first number after LIMIT is the offset, and the second number is the number of records.
You'd of course first need to do a query for the total count and figure out how many times you'll need to run your select query to get all results.
Alternatively, in Perl you can use an ORM package like DBIx::Class that can handle pagination through sets of results and auto-retrieving them for you.
You can adjust the query to select 10 rows:
select *
from yourtable
order by idcolumn
limit 10;
When iterating over the rows, store the ID of the row you process. After you've processed 10 rows, fetch the next 10:
select *
from yourtable
where idcolumn > stored_id
order by idcolumn
limit 10;
Continue the last query until it returns less than 10 rows.
For first page:
SELECT *
FROM table1
ORDER BY
field
LIMIT 0, 10
For seconds page:
SELECT *
FROM table1
ORDER BY
field
LIMIT 10, 10
etc.