使用postgres在带轨道的DISTINCT ID中订购

时间:2015-07-25 07:38:01

标签: ruby-on-rails postgresql

我有以下代码用micropost_id列连接两个表微博和活动,然后根据具有不同微博id的活动表的created_at进行排序。

 Micropost.joins("INNER JOIN activities ON 
 (activities.micropost_id = microposts.id)").
 where('activities.user_id= ?',id).order('activities.created_at DESC').
 select("DISTINCT (microposts.id), *")

应该返回整个微柱。这在我的开发环境中不起作用。

(PG::InvalidColumnReference: ERROR:  for SELECT DISTINCT, ORDER BY expressions must appear in select list

如果我在SELECT DISTINCT中添加activities.created_at,我会得到重复的微博ID,因为它有不同的activities.created_at列。我已经做了很多搜索到达这里。但是由于这种postgres条件,问题总是存在,以避免随机选择。

我想根据activities.created_at的顺序选择不同的micropost _id。

请帮助..

2 个答案:

答案 0 :(得分:3)

首先,我们需要快速介绍SELECT DISTINCT实际正在做的事情。它看起来像就像一个很好的关键字,以确保你只回到不同的值,这不应该改变任何东西,对吧?除非您在幕后发现,GROUP BY实际上更像是activities。如果您想选择某些不同的值,您只能按照您选择的相同值来订购该结果集 - 否则,Postgres不知道该怎么做。

要解释模糊性的来源,请考虑CREATE TABLE activities ( id INTEGER PRIMARY KEY, created_at TIMESTAMP WITH TIME ZONE, micropost_id INTEGER REFERENCES microposts(id) ); INSERT INTO activities (id, created_at, micropost_id) VALUES (1, current_timestamp, 1), (2, current_timestamp - interval '3 hours', 1), (3, current_timestamp - interval '2 hours', 2) 的这一组简单数据:

1, 3, 2

你在问题​​中说过你想要"不同的micropost_id" "基于活动的顺序.created_at"。通过降序created_at(1)可以轻松订购这些活动,但21, 2都具有相同的micropost_id 1.因此,如果您希望查询返回微博ID,如果它返回2, 1SELECT micropost_id FROM activities JOIN microposts ON activities.micropost_id = microposts.id GROUP BY micropost_id ORDER BY MAX(activities.created_at) DESC

如果您可以回答上述问题,则需要采取相应的逻辑并将其移至查询中。让我们这么说吧,我认为这很有可能,你希望这是一个最近被采取行动的微博列表。在这种情况下,您希望按照最近活动的降序对微博进行排序。 Postgres可以通过多种方式为您做到这一点,但最简单的方法是:

SELECT DISTINCT

请注意,我已经删除了GROUP BY位,转而使用MAX(activities.created_at),因为Postgres会更好地处理它们。 Micropost.select('microposts.*') .joins("JOIN activities ON activities.micropost_id = microposts.id") .where('activities.user_id' => id) .group('microposts.id') .order('MAX(activities.created_at) DESC') 位告诉Postgres,对于具有相同micropost_id的每组活动,只按最近的排序。

您可以将上述内容翻译为Rails,如下所示:

String[] columns = { MediaStore.Images.ImageColumns.LATITUDE,
                MediaStore.Images.ImageColumns.LONGITUDE,
                MediaStore.Images.ImageColumns.TITLE,
                MediaStore.Images.ImageColumns.DATA,
                MediaStore.Images.ImageColumns.DATE_TAKEN
        };

  final String orderBy = MediaStore.Images.ImageColumns.DATE_MODIFIED + " DESC";

  Cursor cursor = activity.managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                columns,
                null,
                null,
                orderBy
        );

   int count = cursor.getCount();
   Double latitude, longitude;
   String filePath;
   for (int i = 0; i < count; i++) {
            cursor.moveToPosition(i);
            latitude = cursor.getDouble(cursor.getColumnIndex(MediaStore.Images.ImageColumns.LATITUDE));
            longitude = cursor.getDouble(cursor.getColumnIndex(MediaStore.Images.ImageColumns.LONGITUDE));
            filePath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA));
            Log.i("Image>>",filePath);
            Log.i("Latitude>>", latitude+"");
            Log.i("Longitude>>",longitude+"");

        }

希望这有帮助!如果您想了解有关查询工作原理的更多信息,可以使用this sqlFiddle

答案 1 :(得分:0)

尝试以下代码

Micropost.select('microposts.*, activities.created_at')
.joins("INNER JOIN activities ON (activities.micropost_id = microposts.id)")
.where('activities.user_id= ?',id)
.order('activities.created_at DESC')
.uniq