从子查询中选择DISTINCT ON

时间:2013-12-18 07:40:41

标签: sql postgresql

我有这样的查询:

SELECT user_set, read, last_updated, user_id, pk_id
FROM interaction_log
WHERE user_id = 2002
ORDER BY read, last_updated, user_set

正在使用的数据库是PostgreSQL(9.1),需求如下:

  • 列的顺序可能不会更改(按读取状态排列,然后按上次更新排列,然后按user_set排列)
  • 'read'列是一个整数,只能取'1'或'0'的值。 last_updated是一个正整数,user_set是一个字符串。
  • user_set列必须是唯一的。例如:如果有一个名为'devs'的user_set有3个条目,如下所示:

    1. user_set =“devs”,read = 1,last_updated = 10,user_id = 2002,pk_id = 1
    2. user_set =“devs”,read = 0,last_updated = 30,user_id = 2002,pk_id = 3
    3. user_set =“devs”,read = 0,last_updated = 20,user_id = 2002,pk_id = 2

然后第二个条目(pk_id = 3)应该位于顶部,其他任何一个都应该显示,因为它是'read = 0'然后它的last_updated值是30(高于20)。

SELECT DISTINCT ON(user_set)希望我将user_set作为第一个排序顺序,它将改变顺序,因此我不能这样做。

如果我这样做:

 SELECT DISTINCT ON (user_set) user_set, read, last_updated, thread_id, user_id, id
 FROM message_interaction_log 
    WHERE (user_set, read, last_updated, thread_id, user_id, id) IN
        (SELECT user_set, read, last_updated, thread_id, user_id, id 
            FROM message_interaction_log
            WHERE user_id = 14
            ORDER BY read DESC, last_updated, user_set)

然后,“读取”的'order by'效果是不可见的,并且“读取ASC”和“读取DESC”保持不变。

我尝试过尽我所能,但每次都失败了。任何帮助都会非常感激。

1 个答案:

答案 0 :(得分:0)

您需要将PARTITION BY与OLAP功能一起使用;

SELECT user_set, read, last_updated, user_id, pk_id
FROM (SELECT user_set, read, last_updated, user_id, pk_id,
             ROW_NUMBER() OVER(PARTITION BY user_set 
                               ORDER BY read ASC, last_updated DESC) as rn
      FROM interaction_log
      WHERE user_id = 2002) data
WHERE rn = 1
ORDER BY read ASC, last_updated DESC, user_set ASC

基本上,这会找到每个组的“顶部”行(user_set),并抛出其他所有内容。为获得最佳效果,您可能希望索引为(read ASClast_updated DESCuser_set(任一方向))