我的数据库中有两个表:
(1)PHRASES:
t_phrase
========
I like
They prefer
...
Somebody else wants
和
(2)地点:
n_id t_place
==== =======
1 London
2 Paris
...
N New York
表PHRASES
的行数至少与PLACES
一样多。我需要加入这两个表格,以便为每个表格选择所有place
个phrase
- 但短语需要在各个地方随机分布。整个places
表不是太大:也许,大约3-4,000行,但是它上面会有一个额外的WHERE
子句,它将输出限制在最多约200个位置。 / p>
理想情况下,我希望这是一个SQL语句,但到目前为止,我还没有能够理解这一点。因此,第二个选项是返回(int, varchar, varchar)
行的存储函数。为此,我想到的是:
在某种程度上,这对我来说效率很低,但我无法想出更好的东西。
你能提出更好的建议吗?或者,甚至更好,一个语句SQL,也许?
提前致谢。
编辑:请注意,不应在结果集中重复这些短语。总有至少与地方一样多的短语。
答案 0 :(得分:2)
WITH p AS (
SELECT place, row_number() OVER () AS rn
FROM t_place
WHERE <some condition>
)
, ph AS (
SELECT phrase, row_number() OVER (ORDER BY random()) AS rn
FROM t_phrase
)
SELECT ph.phrase, p.place
FROM p
JOIN ph USING (rn);
如果你在两个表上施加一个真正的随机顺序,它将不再随机,它只会变慢。我对短语强加了随机顺序,因为:
总有至少与地方一样多的短语。
需要使用更大的设置来完成,以免某些非随机部分被切断。另一方面,对于较小的集合(地点),任何数字序列没有间隙是好的,所以我选择最快的方式。
我的示例使用CTE,但也可以使用子查询来完成。 CTE和window functions都需要PostgreSQL 8.4或更高版本。
答案 1 :(得分:0)
我认为以下内容可行:
select (select phrase from phrases order by random() limit 1),
place
from places
应该为每一行调用select中的select,因此每次都应该返回一个不同的值。
如果您只想随意排列短语和地点,可以使用Windows功能:
select ph.phrase, p.place
from (select place, row_number() over (order by place) as seqnum
from places p
) p join
(select phrase, row_number() over (order by random()) as seqnum
from phrases
) ph
on p.seqnum = ph.seqnum
按地点(或任何字段都可以)对地点进行排序。它随机化短语,并加入生成的行号。