如何根据用户配额限制MySQL结果

时间:2015-10-08 08:07:31

标签: mysql limit

今天我的SQl问题是如何根据用户配额限制一些查询结果。

这是用例:

  • 用户拥有1 ... N个网站,其中包含1 ... N个网页
  • 用户有一个scan_quota,允许他(或不允许)访问他的网页

用户

+-----+------------+
| id  | scan_quota |
+-----+------------+
|   1 |          0 |
|   2 |         10 |
|   3 |         20 |
+-----+------------+

网站

+-----+---------+------------------------------------------------+
| id  | user_id | url                                            |
+-----+---------+------------------------------------------------+
|   1 |       1 | http://www.site1.com                           |
|   2 |       2 | http://www.site2.com                           |
|   3 |       3 | http://www.site3.com                           |
+-----+---------+------------------------------------------------+

网页

+-------+------------+--------------------------------------+---------------------+
| id    | website_id | url                                  | last_scan_date      |
+-------+------------+--------------------------------------+---------------------+
| 1     |          1 | http://wwww.site1.com/page1          | 2015-07-02 21:00:56 |
| 2     |          2 | http://wwww.site2.com/page1          | 2015-07-02 21:01:36 |
| 3     |          3 | http://wwww.site3.com/page1          | 2015-07-02 21:00:32 |
+-------+------------+--------------------------------------+---------------------+

我每周都希望获得一个必须根据用户scan_quota进行扫描的网页网址列表。

通过这个简单的查询,我可以获得所有页面:

SELECT us.id, ws.user_id, wp.id, wp.website_id, wp.url 
FROM users us, webpages wp, websites ws 
  WHERE us.id = ws.user_id 
    AND wp.last_scan_date < '2015-10-08' 
    AND ws.id = wp.website_id 
  ORDER BY wp.website_id ASC;

但是一旦我想根据用户scan_quota限制结果,我就会迷失,因为全局LIMIT不会实现我想要的,我不知道如何使用JOIN(INNER或LEFT)来达到我的目标

我已经创建了一个SQL Fiddle来轻松使用我的用例。

感谢您的建议和帮助!

解决方案未优化

在第一个查询中,我提取用户ID和扫描配额,然后循环遍历它们以使用union all构建我的最终查询(允许每个用户使用LIMIT):

$query .= "(SELECT ws.user_id, wp.id, wp.website_id, wp.url FROM webpages wp, websites ws WHERE ws.user_id = ".$user_id." 
                    AND wp.last_scan_date < '2015-10-08' 
                    AND ws.id = wp.website_id LIMIT ".$scan_pages.") union all ";

如果您有办法将这两个查询分组为一个或优化的一个,那就让我们分享。

我也在尝试使用变量和子查询(比如我这个例子:https://stackoverflow.com/a/13187418/2295192),但现在没有运气......

1 个答案:

答案 0 :(得分:5)

请使用此查询,您将获得所需的结果。 您不需要添加您的用户ID。对于每个用户,您可以根据Scan_quota设置限制。

SELECT
  ws.user_id,
  wp.id AS webPageID,
  wp.website_id,
  @page_counter :=IF (
               (wp.website_id != "") ,
                @page_counter + 1,
                @page_counter
               ) AS totalwebpages,
  wp.url
FROM
  (SELECT @page_counter := 0) p,
  webpages AS wp
  LEFT JOIN websites AS ws ON ws.id = wp.website_id
  LEFT JOIN users AS us ON us.id = ws.user_id
  LEFT JOIN (
    SELECT
    @limit_scanQuota := @limit_scanQuota +sum(users.scan_quota) as limitScanQuota,
    users.id
   FROM
    (SELECT @limit_scanQuota := 0) s,
    users
     GROUP BY
    users.id
    ) AS limitQuota ON limitQuota.id = us.id    
WHERE
   date(wp.last_scan_date) < '2015-10-08'
  AND @page_counter<limitQuota.limitScanQuota
GROUP BY
  wp.id
ORDER BY
  wp.id ASC