mysql offset true behaviour - php

I'm creating a pagination with a where clause.
I need to know the true behaviour of the offset.
Is the offset calculated based on all the rows that match the where clause? Or
The offset is calculated like an id and all rows are considered. Eg. If you specify an offset of 5, rows will be returned starting from the 6th row in the table even of the first 4 rows don't match the where clause?
Edit: I want to be sure since the second behaviour would be totally incorrect and cause problems.
Thanks for your answers. I can't comment as my browser fails at javascript and ajax horribly.

Yes the offset is calculated based on all rows that matches the where clause. Just try it.

Are you talking about using the LIMIT clause? LIMIT puts a cap on the number of successful matches, not the total matches. The offset portion of limit is calculated from the matches rather than all eligible rows. MySQL will not necessarily scan rows in a given order and may not scan some rows at all, so it wouldn't short change you rows if a failed match had a lower index.

Related

How to display the column value descending when the column having spacial characters in mysql

How to display the column desc order when the column having spacial chars in mysql
I am using the follow query but not display correctly
SELECT quotation_pno FROM crm_quotation order by quotation_pno desc
My output coming like this
quotation_pno
PT/17/999
PT/17/1533
PT/17/1532
PT/16/1531
I want my output like this
quotation_pno
PT/17/1533
PT/17/1532
PT/17/999
PT/16/1531
Please help me
I'd argue, that the output is correct, but your assumptions are not. It looks to me, as if quotation_pno is some kind of textual column, right?
The sorting assumes, that you want to sort text and this works this way:
Set i to 0
Compare the i-th character of two strigns
If they are the same and the end is not reached, increase i by 1 and proceed with step 2
Otherwise order the two strings according to the value at the i-th position
(There are some things elided and the pseudocode is boiled down to the very basic, needed to understand the principle).
Applied to your example this means, when the comparison compares PT/17/999 and PT/17/1533 it looks at the characters 0 to 5 and "sees" that they are equal. When it compares the characters at position 6, they are '9' and '1'. Since the character '9' is considered to be greater than '1', PT/17/999 is placed before PT/17/1533.
How to solve the issue?
There are some ways coming into my mind, that will allow you to achieve the desired sort order.
First, you could prepend the numbers with zeros. This will allow you to re-use most of your existing structure, but will result either in very many zeros, or a system that is somehow limited, since you will be restricted to the number of digits you decided to use (or the sort will fail again).
The second possibility is, to store the parts in (additional) numerical columns in the table, e.g. one for year and one for the order number in this year. This is the more flexible approach, but involves more changes.

How can I write an SQL query offset by x rows

I'm trying to figure out the fastest way to get x rows from a table that are offset by x rows and ordered by a date column.
The problem I have is I'm paginating the rows from the query into pages of 10 rows per page, but I only need the nth page.
For example if I only need page 4 from the table, I need to select all the rows:
SELECT * FROM posts ORDER BY date
Then I need to paginate the array using PHP and get the 4th page (if it exists). This is less than ideal as it seems a waste to have to get the whole table.
Is there a better way to query the table in this situation?. For example if I have 10 posts per page and I want the the 4th page, is there a way to offset the query so it starts from the 30th row? (and ordered by date).
You're looking for LIMIT
SELECT * FROM posts ORDER BY date LIMIT 10, 20
Where 10 is offset and 20 is the number of rows
LIMIT is the answer. According to MySQL documentation,
The LIMIT clause can be used to constrain the number of rows returned
by the SELECT statement. LIMIT takes one or two numeric arguments,
which must both be nonnegative integer constants (except when using
prepared statements).
With two arguments, the first argument specifies the offset of the
first row to return, and the second specifies the maximum number of
rows to return. The offset of the initial row is 0 (not 1):
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15

Finding Interval of a data present on latest 2 dates

I'm developing a web-based tool that can help analyze number intervals that occurs in a 6-digit lottery.
Let us focus on a certain number first. Say 7
The sql query I've done so far:
SELECT * FROM `l642` WHERE `1d`=7 OR `2d`=7 OR `3d`=7 OR `4d`=7 OR `5d`=7
OR `6d`=7 ORDER BY `draw_date` DESC LIMIT 2
This will pull the last two latest dates where number 7 is present
I'm thinking of using DATEDIFF but I'm confused on how to get the previous value to subtract it on the latest draw_date
My goal is to list the intervals of numbers 1-42 and I'll plan to accomplish it using PHP.
Looking forward to your help
A few ideas spring to mind.
(1) First, since you perfectly have your result set ordered, use PHP loop on the two rows getting $date1 =$row['draw_date']. Then fetch next/last row and set $date2 =$row['draw_date']. With these two you have
$diff=date_diff($date1,$date2);
as the difference in days.
(2)
A second way is to have mysql return datediff by including a rownumber in the resultset and doing a self-join with aliases say alias a for row1 and alias b for row2.
datediff(a.draw_date,b.drawdate).
How one goes about getting rownumber could be either:
(2a) rownumber found here: With MySQL, how can I generate a column containing the record index in a table?
(2b) worktable with id int auto_increment primary key column with select into from your shown LIMIT 2 query (and a truncate table worktable between iterations 1 to 42) to reset auto_increment to 0.
The entire thing could be wrapped with an outer table 1 to 42 where 42 rows are brought back with 2 columns (num, number_of_days), but that wasn't your question.
So considering how infrequent you are probably doing this, I would probably recommend not over-engineering it and would shoot for #1

MySQL Query Result Offset With Limit With New Result Possibility?

I'm working on an application that uses a scroll load system of 20 or so results loading into a feed at a time as you scroll. This feed consists of constantly added user generated content. Which means the result set can change per query that is offset by X.
So let's say we load 20 results, then scroll, another 20, and then before scrolling more to load the next 20, another user has uploaded a new piece of content, which effectively would present a duplicate in the next set of 20 results for the feed because we're using OFFSET to get additional results, and the total result set is getting shifted by 1 with this addition of new content that falls into the conditions of the query.
What is the best and most efficient way around this? We've dabbled with using the id of a row in a where condition to prevent duplicate results, and only using limit without offset for new results fetched.. so we could do WHERE id < 170 LIMIT 20, WHERE id < 150 LIMIT 20, WHERE id < 130 LIMIT 20, etc.. to control and prevent duplciates... HOWEVER, this does not work in every possible scenario as our result sets aren't always ordered with the id column ordered by DESC..
Soo.. what other options are there?..
Why are you using the where clause instead of limit with the offset option? Limit can take two arguments. The offset argument seems to do exactly what you want. For instance:
limit 100, 20
Takes 20 rows starting at the 101st row. Then:
limit 120, 20
Takes 20 rows starting at the 121st row. (The offsets start at 0 rather than 1 in MySQL counting.)
The one enhancement that you need to make is to ensure that the sort order for the records is stable. A stable sort is, essentially, one where there are no sort keys with the same value. To make this happen, just make the id column the last column in the sort. It is unique, so if there are any duplicate sort keys, then the addition of the id makes the sort stable.
You might want to try a database solution. On the initial request, create and populate a table. Use that table for the feed.
Make sure the tablename starts with something consistent, like TableToFeedMyApp, and ends with something guaranteed to make it unique. Then set up a scheduled job to find and drop all these tables that were created earlier than whatever you deem to be a certain interval.

select inbetween elements in mysql?

I am trying to implement the pagination in php. I am using the Mysql as back end database. I am trying to implement the pagination logic.
I would be having lots of record. But the user will see only 10 at a time.
Now to show the first page, i do a
SELECT * from USERS LIMIT 10.
Now to get the next 10 and the subsequent 10 records i am not able to write a query. Please help me fetch the in between records to support pagination logic. Also provide if any other suggestions for pagination.
You should use the OFFSET option.
SELECT * FROM Users LIMIT 10 OFFSET 10 (or 20, or 30);
That way you just pass the start position in the request when you hit next (or the page number) and you'll retrieve the records you want.
MySQL's limit feature can take two arguments:
select * from USERS limit 10,10
The above would retrieve 10 rows starting at row 10. Bear in mind that the MySQL row offset is 0 based, not 1. The first argument is the starting row, the second is the page size.
Also, if your page size is consistent, all you need to do is pass in the current page (default to zero). That would then allow you to specify the start row as a page * size.

Categories