Postgres 9.5.2在开发与生产中的排序方式不同

时间:2016-04-23 21:01:55

标签: postgresql sorting

已更新

在使用postgresql的rails应用程序中,我编写了一个Active Record查询来查找一组志愿者记录,然后按first_name,然后last_name,然后email订购。此外,first_namelast_name可能是null(两者都是null或两者都不是null)。 sql Active Record生成如下所示:

SELECT DISTINCT LOWER(COALESCE("volunteers"."first_name", "volunteers"."email")), LOWER(COALESCE("volunteers"."last_name", "volunteers"."email")), LOWER("volunteers"."email"), "volunteers".* 
FROM "volunteers" 
INNER JOIN "volunteer_list_connectors" ON "volunteer_list_connectors"."volunteer_id" = "volunteers"."id" 
INNER JOIN "volunteer_lists" ON "volunteer_lists"."id" = "volunteer_list_connectors"."volunteer_list_id" 
WHERE ((volunteer_lists.organizer_id = 1 AND organizer_type = 'Organization') OR (volunteer_lists.organizer_id IN (1) AND organizer_type = 'Collaborative'))  
ORDER BY 
  LOWER(COALESCE("volunteers"."first_name", "volunteers"."email")) ASC, 
  LOWER(COALESCE("volunteers"."last_name", "volunteers"."email")) ASC, 
  LOWER("volunteers"."email") ASC

使用Postgres'psql工具,我复制&在我的开发机器和服务器上将该sql粘贴到Postgres中。在我的开发机器(Mac)上,sql因此对以下列表进行排序:

  1. Volunteer [first_name:'Alex',last_name:'Diego',电子邮件: 'a.diego@person.com']
  2. 志愿者[first_name:null,last_name:null,电子邮件: 'cxxr@person.com']
  3. 志愿者[first_name:'Josh',last_name:'Broger',电子邮件: 'broger@person.com']
  4. 志愿者[first_name:'Josh',last_name:'Broger',电子邮件: 'jcool@person.com']
  5. 志愿者[first_name:'Josh',last_name:'Kenton',电子邮件: 'aj@person.com']
  6. 在我的生产环境(Ubuntu)中,Postgres通过对列表进行排序来响应相同的代码:

    1. 志愿者[first_name:null,last_name:null,电子邮件: 'cxxr@person.com']
    2. Volunteer [first_name:'Alex',last_name:'Diego',电子邮件: 'a.diego@person.com']
    3. 志愿者[first_name:'Josh',last_name:'Broger',电子邮件: 'broger@person.com']
    4. 志愿者[first_name:'Josh',last_name:'Broger',电子邮件: 'jcool@person.com']
    5. 志愿者[first_name:'Josh',last_name:'Kenton',电子邮件: 'aj@person.com']
    6. 不同之处在于,只有电子邮件地址的志愿者总是排在其他志愿者之前。生产环境和开发环境都运行PostgreSQL 9.5.2。两者都运行Rails 4.2.6。

      我无法弄清楚为什么我的应用程序在开发与生产方面的表现不同。

      有人有什么想法吗?任何进一步探索的帮助/领域都非常感谢!

      更新2

      根据评论中的要求,这是我的开发机器和生产机器的psql输出。我略微改变了查询以使图片可读。在此查询中,我添加了LIMIT 10,我只要求first_namelast_nameemail而不是整个记录。您必须接受我的说法,即两个数据库都包含仅volunteers地址的email条记录,以及包含first_namelast_name和{{1}的记录}。如果我的生产数据库按预期工作,其输出看起来就像第一张图片中的输出。

      此屏幕抓取显示我的开发机器的email输出(好):

      This screen grab shows <code>psql</code> output from my dev machine (good)

      此屏幕抓取显示我的生产计算机的输出psql(错误)。因为这是输出中的真实用户数据,所以我模糊了电子邮件地址。但重要的是,即使电子邮件地址的第一个字母为“Z”,psqlfirst_name = null的记录也始终排在第一位:

      This screen grab shows <code>psql</code> output from my production machine (bad)

      我可能错了,但我认为生产机器输出应显示每列中的电子邮件地址last_name = null是否正常运行

      ANSWER

      感谢@ClémentPrévost(和@muistooshort问我正确的问题!)我能够找到答案:我认为生产中的记录没有正确排序实际上COALESCE()中有空字符串和first_name代替last_name值(null仅过滤COALESCE()个值,而不是空白字符串)。我用null更新了我的代码,一切都开始正常排序!

      NULLIF("volunteers"."first_name", \'\')

1 个答案:

答案 0 :(得分:1)

那些真的是空的还是空字符串?

您可以使用\pset null ¤来区分这两者。

PS:问题评论中的讨论很棒!