PostgreSQL - 选择distinct - 在select中没有返回的order by字段

时间:2011-11-29 00:45:17

标签: c# sql nhibernate postgresql

我们目前正在将我们的数据库后端从Firebird迁移到PostgreSQL。我们将NHibernate用作ORM,尽管SQL中存在一些差异,但转换仍然非常简单。

我们有一个查询,我们使用NHibernate.CreateSQLQuery执行,因为我们自己构建SQL。该查询返回传入的UserID中最近访问最多5个Ninja名称的字符串List。

使用以下SQL在Firebird中没问题;

 SELECT FIRST 5 DISTINCT NI.NINJA_NAME
 FROM NINJA_ACCESS NA 
      INNER JOIN NINJAS NI ON NA.NINJA_ID = NI.NINJA_ID
 WHERE NA.USER_ID = 1
 ORDER BY NI.NINJA_ACCESS_DATE DESC

返回有序(按访问日期降序排列)字符串列表。

现在在PostgreSQL中,我们遇到了这个简单查询的问题;

 SELECT DISTINCT ON (NI.NINJA_NAME) NI.NINJA_NAME
 FROM NINJA_ACCESS NA 
      INNER JOIN NINJAS NI ON NA.NINJA_ID = NI.NINJA_ID
 WHERE NA.USER_ID = 1
 ORDER BY NI.NINJA_ACCESS_DATE DESC
 LIMIT 5

似乎我们无法返回单个“不同”数据列,并且在未包含在select中的单独列上执行排序。除非我们在select中包含Access_Date列,否则上述SQL中的任何变体都不起作用。

我们如何在PostgreSQL中解决这个简单的查询?

旁注:这是我们的忍者管理系统的一个重要问题,忍者坚持认为它有效!!!

1 个答案:

答案 0 :(得分:2)

此查询应该是等效的:

SELECT n.ninja_name
      ,max(n.ninja_access_date) AS max_access_date
FROM   ninja_access na 
JOIN   ninjas n USING (ninja_id)
WHERE  na.user_id = 1
GROUP  BY n.ninja_name
ORDER  BY 2 DESC
LIMIT  5;
  • ORDER BY 2只是ORDER BY max(n.ninja_access_date)
  • 的简写
  • 我们需要max(n.ninja_access_date)ninja_name获取最多最近条目。
    并按降序排序以获取最新名称。
  • JOIN ninjas n USING (ninja_id)
    的简写 JOIN ninjas n ON n.ninja_id = na.ninja_id

您不必在SELECT列表中包含访问日期。仅获取名称:

SELECT n.ninja_name
FROM   ninja_access na 
JOIN   ninjas ni USING (ninja_id)
WHERE  na.user_id = 1
GROUP  BY n.ninja_name
ORDER  BY max(n.ninja_access_date) DESC
LIMIT  5;