Mi solución en PL/pgSQL basada. He encontrado una mejor manera, que no es necesario tabla temporal adicional (usando INSERT
a la mesa en el cuerpo de la función), es decir que puede utilizar esta función para obtener el resultado directamente:
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';
Aquí es un poco de los Ensayos conducir:
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);
Resultado:
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)
¿Cuántos dominios tiene en esa tabla? Si hay más de 16, ¿cómo debería comportarse la consulta? –
Sí, mucho más que 16. Si al seleccionar 30 por dominio excede el límite máximo, deje de obtener más URL. Ejemplo: si el límite fue 70, obtenga 30 de Google, 30 de Facebook, 10 de Ebay y nadie de los demás. –
¿Y qué dominios deberían tener preferencia? ¿Cómo se determina eso? –