我有一堆存储在表中的URL等待被脚本删除。但是,其中许多网址来自同一网站。我想以“网站友好”的顺序返回这些网址(也就是说,尝试连续避免来自同一网站的两个网址),这样我就不会在短时间内通过制作太多的http请求而意外阻止
数据库布局是这样的:
create table urls ( site varchar, -- holds e.g. www.example.com or stockoverflow.com url varchar unique );
示例结果:
SELECT url FROM urls ORDER BY mysterious_round_robin_function(site); http://www.example.com/some/file http://stackoverflow.com/questions/ask http://use.perl.org/ http://www.example.com/some/other/file http://stackoverflow.com/tags
我想到了像“ORDER BY site <> @last_site DESC
”这样的东西,但我不知道如何写这样的东西。
答案 0 :(得分:4)
在我的博客中查看此文章,了解有关其工作原理的更详细说明:
使用新的PostgreSQL 8.4
:
SELECT *
FROM (
SELECT site, url, ROW_NUMBER() OVER (PARTITION BY site ORDER BY url) AS rn
FROM urls
)
ORDER BY
rn, site
使用旧版本:
SELECT site,
(
SELECT url
FROM urls ui
WHERE ui.site = sites.site
ORDER BY
url
OFFSET total
LIMIT 1
) AS url
FROM (
SELECT site, generate_series(0, cnt - 1) AS total
FROM (
SELECT site, COUNT(*) AS cnt
FROM urls
GROUP BY
site
) s
) sites
ORDER BY
total, site
,虽然效率可能较低。
答案 1 :(得分:3)
我认为你过于复杂了。为什么不使用
订购NewID()
答案 2 :(得分:2)
你要求循环赛,但我认为这很简单
SELECT site, url FROM urls ORDER BY RANDOM()
会做到这一点。即使来自同一站点的URL聚集在db中,它也应该工作。
答案 3 :(得分:0)
如果URL不经常更改,您可以提出一个稍微复杂的工作,您可以定期(夜间?)运行,这将根据存在的不同站点为每条记录分配整数。
您可以做的是编写一个从URL解析域的例程(您应该能够找到几乎可以在任何地方执行此操作的片段。)
然后,您创建一个包含每个唯一域的临时表,以及一个数字。
然后,对于URL表中的每个记录,您在临时表中查找域,为该记录分配存储在那里的号码,并在该临时表的号码中添加一个大号。
然后在剩下的时间里,按数字排序。
以下是您在问题中使用的五条记录的示例:
网址:
临时表:
example.com 1
stackoverflow.com 2
perl.org 3
然后,对于每个URL,您在临时表中查找值,并向其添加3(因为它有3个不同的记录):
网址:
http://www.example.com/some/file 1
http://www.example.com/some/other/file NULL
https://stackoverflow.com/questions/ask NULL
https://stackoverflow.com/tags NULL
http://use.perl.org/ NULL
临时表:
example.com 4
stackoverflow.com 2
perl.org 3
网址:
http://www.example.com/some/file 1
http://www.example.com/some/other/file 4
https://stackoverflow.com/questions/ask NULL
https://stackoverflow.com/tags NULL
http://use.perl.org/ NULL
临时表:
example.com 7
stackoverflow.com 2
perl.org 3
等等,直到你到达 p>
http://www.example.com/some/file 1
http://www.example.com/some/other/file 4
https://stackoverflow.com/questions/ask 2
https://stackoverflow.com/tags 5
http://use.perl.org/ 3
对于很多记录来说,它会很慢。并且很难使用许多插入/删除,但结果将是一个完美的循环排序。
答案 4 :(得分:0)
有一个更简单,更快速的解决方案......
- &GT;它非常快且索引 - &GT;行将以可重复但随机的顺序出现