我有两个查询,一个将从主表中获取一个ID列表,另一个将获取另一个表中与该ID相关的所有记录。
我想将其拆分为结果页面,但我的谷歌搜索只出现在想要每列值有一定数量结果的人身上,而不是想要通过它限制总体数量的人
主表有一个包含记录数的列,因此实际上不需要读取另一个表。该限制将用作最小值,因此如果在限制之后当前组中仍有剩余记录,则它将继续显示它们。这可以以某种方式计算为偏移的一部分,因此它可以从正确的位置开始。
这是我的意思的一个例子:
表1:
ID | GroupID | Value
1 | 1 | x
2 | 1 | x
3 | 2 | x
4 | 2 | x
5 | 2 | x
6 | 3 | x
...
表2(此问题不需要知道的内容):
1
如果限制为3,例如,2
和1
都应显示在第一页上,因为只有3
本身处于限制之下。然后,下一页将从$page = 2;
$limit = 40;
$count = 0;
$current_page = 1;
$query = 'SELECT ID, Records FROM table1';
$stmt = $conn->prepare($query);
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$count += $row['Records'];
if($count > $limit){
$current_page ++;
$count = 0;
if($current_page == $page){
$start_id = $row['ID'];
break;
}
}
}
开始,这将占据整个页面。
我可以手动计算使用PHP,直到达到极限,但如果有很多页面可能最终会变慢(我不知道mysql在这方面是否会更好) 。以下是一个快速举例说明如何获得偏移:
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-date
android:name="com.google.android.maps.v2.API_KEY"
android:value="@string/google_maps_key"/>
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key"/>
答案 0 :(得分:2)
您正在寻找“自定义”Pagination。因此,如果您计划从一个页面跳到另一个页面,则无法使用硬编码的$page
和$current_page
值。当您在特定页面上时,应该动态生成这些值。实际上,您应该在URL的查询部分中包含 ID 列值,以便分页链接可以满足您的业务逻辑。
假设您的 ID 列值从1
开始,您的代码应如下所示:
$id = isset($_GET['id']) && is_numeric($_GET['id']) ? $_GET['id'] : 1;
$limit = 40;
// Display query results based on particular ID number
$query = 'SELECT ID, Records FROM table1 WHERE ID >= ' . $id;
$stmt = $conn->prepare($query);
$stmt->execute();
$rowCount = $stmt->rowCount();
if($rowCount){
$total = 0;
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
if($total <= $limit){
$total += $row['Records'];
// Display $row details here
}else{
// Get the next $id value
$id = $row['ID'];
break;
}
}
}
// Display relevant ID links
$query = 'SELECT * FROM table1';
$stmt = $conn->prepare($query);
$stmt->execute();
$idArr = array();
$total = 0;
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
if($total == 0){
$idArr[] = $row['ID'];
}
if($total <= $limit){
$total += $row['Records'];
}else{
$total = 0;
}
}
foreach($idArr as $idValue){
if($idValue == $id){
echo '<a>'.$idValue.'</a> ';
}else{
echo '<a href="?id='.$idValue.'">'.$idValue.'</a> ';
}
}
旁注:如果表格的 ID 列值未从1
开始,请使用单独的查询来获取第一个 ID 值并更新以下语句
$id = isset($_GET['id']) && is_numeric($_GET['id']) ? $_GET['id'] : <FIRST_ID_VALUE>;
答案 1 :(得分:1)
如果您只需要创建“下一步”按钮,可以尝试这种方式:
select t1.ID, t1.Records
from table1 t1
left join table1 t2
on t2.ID < t1.ID
and t2.ID > :last_selected_id_1
where t1.ID > :last_selected_id_2
group by t1.ID, t1.Records
having coalesce(sum(t2.Records), 0) < :limit
order by t1.ID
:last_selected_id_x
是当前页面的最后一个ID或第一页的0
。
http://rextester.com/FJRUV28068
您可以使用MySQL会话变量来创建页面链接:
select page, min(ID) as min_id, max(ID) as max_id
from (
select ID
, @page := case when @sum = 0 then @page + 1 else @page end as page
, @sum := case when (@sum + Records) >= :limit
then 0
else @sum + Records
end as sum
from table1
cross join (select @sum := 0, @page := 0) initvars
order by ID
) sub
group by page
结果如下:
page | min_id | max_id
1 | 1 | 2
2 | 3 | 3
3 | 4 | 4
http://rextester.com/LQVJWP18655
请注意,正式(截至文档)不建议使用类似的会话变量(在一个语句中读取和写入)。功能版本可能会破坏您的代码。
答案 2 :(得分:1)
这是我最终得到的结果,我最终根据Rajdeeps的答案进行了调整,但进行了调整,以便它可以进行排序。
$query = 'SELECT ID, Records FROM table1 ORDER BY something';
$stmt = $conn->prepare($query);
$stmt->execute();
$id_array = array(); // For storing each ID
$current_ids = array(); // For storing the current ID pages
$initial_ids = array(); // For storing the first page, in case the page is too high
$count = 0;
$current_page = 1;
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$already_reset = false;
// Move the session to the next page if it's more over the limit than under
// For example, if a limit of 10 has 6 records already, and the next ID is 9 records, then start a new page
if($id_array and $count + $row['Records'] / 2 > $max_links){
array_push($id_array, $last_id);
$current_page ++;
$count = 0;
$already_reset = true; // Set a marker so that if this ID is larger than the limit then don't start a 2nd new page
}
// Backup the first results in case page is too high and needs to be reset to 1
if($current_page == 1){
array_push($initial_ids, $row['ID']);
}
$count += $row['Records'];
// The values that appear here are the results for the selected page
// They may not be in sequence so store the individual IDs
if($_GET['page'] == $current_page){
array_push($current_ids, $row['ID']);
}
// Start a new page if over the limit
if($count > $max_links and !$already_reset){
$current_page ++;
$count = 0;
array_push($id_array, $row['ID']);
}
$last_id = $row['ID'];
}
array_push($id_array, $last_id);
$total_pages = count($id_array);
// If page is invalid revert to default
if(!$current_ids){
$current_ids = $initial_ids;
$_GET['page'] = 1;
}
$_GET['page'] = max(1, min($total_pages, intval($_GET['page'])));
$current_ids
是当前页面的ID数组,$total_pages
非常自我解释。