我有一個URL表和一個屬性是域。我如何選擇具有相同屬性的有限數量的行?
假設我有100個來自谷歌的URL,100個來自Facebook,100個來自易趣,其他域也一樣,但我想從Google搜索前30個網址,來自Facebook的30個來自Ebay,來自其他網站的30個限制爲最多500個網址。
我該怎麼做?
我有一個URL表和一個屬性是域。我如何選擇具有相同屬性的有限數量的行?
假設我有100個來自谷歌的URL,100個來自Facebook,100個來自易趣,其他域也一樣,但我想從Google搜索前30個網址,來自Facebook的30個來自Ebay,來自其他網站的30個限制爲最多500個網址。
我該怎麼做?
下面的SQL解決了我的情況,但網址是無序因爲ROW_NUMBER不遵守命令。我認爲這個SQL需要一些改進。
SELECT url,row_number FROM(
SELECT url,row_number() OVER (PARTITION BY domain) FROM website
WHERE domain IN
(SELECT DISTINCT domain FROM link)
) AS links
WHERE row_number <= 10
LIMIT 25
您可以編寫'PARTITION BY c ORDER BY ctid'或指定其他列進行排序。無論如何,很好的答案。 –
我在PL/pgSQL的解決方案爲主。我發現了一個更好的辦法,你不需要額外的臨時表(在函數體使用INSERT
到該表),即你可以使用該功能來獲得直接的結果是:
CREATE OR REPLACE FUNCTION getURLs(singleLimit integer, totalLimit integer)
RETURNS SETOF RECORD AS $$
DECLARE
dom text;
nrOfDomains integer;
i integer;
lim integer;
remainder integer;
BEGIN
nrOfDomains := totalLimit/singleLimit; -- integer division (truncate)
remainder := totalLimit%singleLimit;
IF remainder <> 0 THEN
nrOfDomains := nrOfDomains + 1;
END IF;
i := 1;
FOR dom IN SELECT DISTINCT domain FROM website LIMIT nrOfDomains
LOOP
IF i = nrOfDomains AND remainder <> 0 THEN
lim := remainder;
ELSE
lim := singleLimit;
END IF;
RETURN QUERY SELECT * FROM website WHERE domain = dom LIMIT lim;
i := i + 1;
END LOOP;
RETURN;
END $$
LANGUAGE 'plpgsql';
下面是一些測試 - 開車:
postgres=> CREATE TABLE website(url text, domain text);
CREATE TABLE
postgres=> INSERT INTO website
SELECT 'http://' || d.column1 ||'/' || n, d.column1
FROM generate_series(1, 100) n CROSS JOIN
(VALUES ('google'), ('facebook'), ('ebay')) d;
INSERT 0 300
postgres=> SELECT * FROM getURLs(10, 25) website(url text, domain text);
結果:
url | domain
--------------------+----------
http://google/1 | google
http://google/2 | google
http://google/3 | google
http://google/4 | google
http://google/5 | google
http://google/6 | google
http://google/7 | google
http://google/8 | google
http://google/9 | google
http://google/10 | google
http://facebook/1 | facebook
http://facebook/2 | facebook
http://facebook/3 | facebook
http://facebook/4 | facebook
http://facebook/5 | facebook
http://facebook/6 | facebook
http://facebook/7 | facebook
http://facebook/8 | facebook
http://facebook/9 | facebook
http://facebook/10 | facebook
http://ebay/1 | ebay
http://ebay/2 | ebay
http://ebay/3 | ebay
http://ebay/4 | ebay
http://ebay/5 | ebay
(25 rows)
我明白你爲什麼寫'IF 500%30 <> 0「,但它讓我笑了起來。 :) –
+1。值得注意的是,如果你想讓這些域被隨機排序,你可以使用'FOR d IN SELECT DISTINCT domain FROM website LIMIT nrOfDomains ORDER BY RAND()',或者如果你想讓它們以某種其他方式排序去做吧。 –
@Chris Cunningham:是的,我將'500%30'改爲更通用的'totalLimit%singleLimit'。 –
你在該表中有多少個域?如果超過16個,那麼查詢應該如何表現? –
是的,遠遠超過16個。如果選擇每個域超過最大限制30個,請停止獲取更多網址。例如:如果限制爲70,則從Google獲得30個,從Facebook獲得30個,從Ebay獲得10個,並且從其他人獲得10個。 –
哪些域名應該有偏好?這是如何確定的? –