1

我有以下数据集:

update (id, update_time)
1    <a timestamp>
2    <a timestamp>

item_update (update_id, item_id)
1    327
1    328
1    496
2    345
2    477

我想要做的是在页面中按如下方式显示它们:

2012 年 3 月 6 日:
327
328
496

2012 年 7 月 7 日:
345
477

或多或少。问题是数据集预计会变得非常大。我不能在一个页面中拥有所有这些。但是,如果我只是将它们限制为任意数量,那么这些组会在中间被切断。如果我通过更新来限制它们,那么我可能会在一个页面中得到太少而在另一页面中得到太多。

如何限制结果集,以便在不超过一定数量的项目的情况下获得尽可能多的组(更新)?

4

4 回答 4

1

以下查询

select a.id, floor(ifnull(sum(b.update_count),0) / 50) as start_page
from updte as a
left join
    (select update_id, case when count(1) > 50 then 50 else count(1) end as update_count
     from item_update group by update_id) as b
  on a.id > b.update_id
group by a.id

将为您提供每个组应该开始的页码update_id(假设我们希望在页面上显示不超过 50 个项目,除非组中的项目超过 50 个)。知道start_page每个update_id您只能显示相关update_iditem_update.

于 2012-07-24T20:14:51.977 回答
1

我假设您不想拆分组,那么您可以简单地

select update_id, count(*) cnt from item_update group by update_id;

这将为您提供每个 update_id 的计数。然后,只需遍历 update_ids,直到您的累积达到(或超过)您的页面最大值,然后为所有这些 update_ids 触发另一个查询......

可能存在边缘情况,其中一个更新组有 1 个项目,下一个有 1000 个项目......在那里,让您的分页在组上中断可能是有意义的......

page1

group1
  item1
  item2
  item3
group2
  item1
  item2

page2

group2
  item3
  item4
  etc...

那么只需将limit子句与排序一起使用......

于 2012-07-24T19:58:31.263 回答
0

您可以使用此解决方案:

SELECT     b.update_time, a.item_id           
FROM       item_update a
INNER JOIN updte b ON a.update_id = b.id
LEFT JOIN  item_update c ON a.update_id = c.update_id
      AND  a.item_id <= c.item_id
GROUP BY   a.update_id, a.item_id
HAVING     COUNT(1) <= 2

2子句中的HAVING是每组要限制的项目数(通过每组最高的nitem_id来限制)。您可以使用演示摆弄此解决方案:

SQLFiddle 演示

请注意,如果您将 更改2为 a 3,您将在 3 月 6 日获得更多结果。


如果您希望结果分层显示,您可以这样做:

SELECT a.val
FROM
(
    SELECT     CONCAT('- - - -> ', a.item_id) AS val,
               CONCAT(b.update_time, a.item_id) AS orderfactor
    FROM       item_update a
    INNER JOIN updte b ON a.update_id = b.id
    LEFT JOIN  item_update c ON a.update_id = c.update_id AND a.item_id <= c.item_id
    GROUP BY   a.update_id, a.item_id
    HAVING     COUNT(1) <= 2

    UNION ALL

    SELECT DATE_FORMAT(update_time, 'On %M %e, %Y:'), 
           update_time
    FROM   updte
) a
ORDER BY a.orderfactor

SQLFiddle 演示

于 2012-07-24T20:01:41.243 回答
0

找到了答案,虽然它并不漂亮。

基本上,我要先找到update_iditem_update中所有的唯一性,如下:

(SELECT * FROM 
    (SELECT update_id 
     FROM item_update
     WHERE update_id < :my_last_id_from_previous_page
     ORDER BY update_id DESC
     LIMIT 0, :limit
) as inner_query
GROUP BY update_id) as outer_query

结果表为我提供了所有必须返回的组,因此剩下的就是小菜一碟:

SELECT item_id, update.id, update_time FROM outer_query
INNER JOIN item_update ON (item_update.update_id = outer_query.update_id)
INNER JOIN update ON (item_update.update_id = update.id)
于 2012-07-24T20:06:54.317 回答