我如何选择具有相同属性的有限数量的行?

时间:2011-07-05 19:41:33

标签: sql postgresql

我有一个URL表,一个属性是域。

假设我有来自Google的100个网址,来自Facebook的100个网址,来自Ebay的100个网址以及其他网域的相同网址,但我想检索来自Google的前30个网址,来自Facebook的30个网址,来自Ebay的30个网址以及来自其他网页的30个网址最多500个网址。

我是怎么做到的?

3 个答案:

答案 0 :(得分:2)

以下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

答案 1 :(得分:1)

这样的事情怎么样:

SELECT url FROM link WHERE domain='Google' LIMIT 30
UNION
SELECT url FROM link WHERE domain='Facebook' LIMIT 30
UNION
SELECT ...

答案 2 :(得分:1)

我的解决方案基于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)