c# - PostgreSQL - 选择不同 - 按字段排序未在选择中返回

标签 c# sql nhibernate postgresql

我们目前正在将我们的数据库后端从 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/

相关文章:

c# - 如何从客户端知道表是否已更新

c# - 在不使用 Regasm 的情况下在 C++ 代码中使用 C# dll

sql - MySQL 通配符 * 和 %

NHibernate 在二级缓存中找不到命名查询结果集

c# - 无法初始化集合但 nhibernate 生成正确的 sql 并在 sql server 中无错误地执行

c# - 父子一对一关系同一张表

c# - asp.net 到 MySql 的问题。尝试从输入返回信息

mysql - 试图弄清楚如何创建这个过程

mysql - 中间表多值查找

linq - NHibernate LINQ 在 Where() 子句中支持 ToLower() 吗?