我们目前正在将我们的数据库后端从 Firebird 迁移到 PostgreSQL。我们使用 NHibernate 作为 ORM,尽管在 SQL 中存在一些差异,但转换过程非常轻松。
我们有一个查询,在我们自己构建 SQL 时使用 NHibernate.CreateSQLQuery 执行。该查询为传入的 UserID 返回最近访问的 5 个忍者名称的字符串列表。
这在使用以下 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
看起来我们无法返回单个“不同”的数据列,并且对未包含在选择中的单独列执行排序。除非我们在选择中包含 Access_Date 列,否则上述 SQL 的任何变体都不起作用。
有什么想法可以解决 PostgreSQL 中的这个简单查询吗?
旁注:这是对我们的 Ninja 管理系统的重要查询,Ninja 坚持认为它有效!!!
最佳答案
这个查询应该是等价的:
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)
是
的简写加入 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;
关于c# - PostgreSQL - 选择不同 - 按字段排序未在选择中返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8304392/