2015-10-08 69 views
1

今天我的SQI問題是如何限制一些基於用戶配額的查詢結果。如何根據用戶配額限制MySQL結果

這裏是用例:

  • 用戶擁有具有1個... N個網站... 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要掃描的網頁的URL列表

有了這個簡單的查詢,我可以得到所有的網頁:只要我想根據用戶scan_quota我迷路了,因爲全侷限制不會acheive我想要什麼限制結果

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; 

但並我不知道如何使用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),但沒有運氣現在...

+0

見http://stackoverflow.com/questions/2129693/using-limit-within-group-by-to-get-n-results-per-group如何獲得每組'N'結果。你的情況唯一的區別是'N'不是一個硬編碼的數字,你可以通過加入用戶表並使用users.scan_quota來得到它。 – Barmar

回答

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 
+0

感謝您給我一個更合適的查詢結構,但我仍然沒有看到如何根據掃描配額限制每個用戶的結果... – hugsbrugs

+0

您希望根據掃描配額爲用戶設置限制..您的意思是如果掃描配額爲那個用戶10,那麼你想爲該用戶設置限制= 10?你想那樣嗎? –

+0

就是這樣!如果用戶將掃描配額設置爲0,則不應爲此用戶返回任何結果。如果用戶的掃描配額設置爲10,但有20個網頁,則只能返回10個。 – hugsbrugs