如何从返回随机行的选择中获取剩余数据

时间:2016-10-19 07:39:36

标签: sql postgresql

如果我从50部电影中选择20部随机电影,

SELECT movieName
FROM movies 
ORDER BY random() 
LIMIT 20

然后如何继续从其余30部电影中随机选择10个?

如果我继续使用上面的代码,则会出现重复的键值错误。

3 个答案:

答案 0 :(得分:4)

生成随机密钥key,然后按md5(movieName || key)排序。跟踪此密钥,以便您可以使用OFFSET使用相同的密钥请求下一组元组。使用相同的键两次将导致相同的顺序。使用不同的密钥将导致不同的顺序。这似乎是随机的,因为像md5这样的散列函数会为类似的输入返回完全不同的结果。

答案 1 :(得分:2)

您需要存储已在某处显示的电影的名称。然后,当您重新运行语句时,在查询中添加where moviename not in (....)以排除已显示的那些。

如果您可以在请求之间保持与数据库的连接,则可以使用临时表来存储已显示的电影:

create temporary table displayed_movies(moviename text);

然后,您可以使用以下语句来显示电影:

with selected as (
  select moviename
  from movies 
  where moviename not in (select d.moviename 
                          from displayed_movies d)
  order by random() 
  limit 20
), inserted as (
   insert into displayed_movies (moviename)
   select moviename
   from selected       
) 
select *
from selected;

每次运行上述语句时,它都会选择一组不同的(随机)电影。如果显示所有电影,则不会返回任何内容。

再次说明:只有在每次调用之间保持与数据库的连接时,这才会起作用。

如果无法保持连接打开(这意味着您无法使用临时表),则需要在应用程序中记住这些名称并生成相应的where moviename not in (...)条件。

答案 2 :(得分:0)

您可以在新查询中使用您的查询:

curl: (3) [globbing] unmatched close brace/bracket in column 21
org.codehaus.jackson.JsonParseException: Unexpected end-of-input in VALUE_STRING
 at [Source: org.apache.catalina.connector.CoyoteInputStream@185ff06c; line: 4, column: 139]

您不会在第一次查询时看到20部电影。在这种情况下,仅仅是选择20部电影的结果,而不是选择其余30部电影中的10部。

请记住,如果您先使用语句,然后再使用此查询,则子选择(您的查询)将返回比其第一次执行时更多的随机电影。

希望肝脏!