【问题标题】:Rewrite a SQL query to work on heroku重写 SQL 查询以在 heroku 上工作
【发布时间】:2010-06-28 13:39:04
【问题描述】:

我将如何重写这个 Rails 查询以在 Heroku (Portegres) 上运行

@students = Student.find(:all, 
                  :conditions =>["(concat(first_name, ' ', last_name) LIKE ?) OR
                                  (concat(first_name, ' ', middle_names, ' ', last_name) LIKE ?)",
                                 "%#{params[:search]}%", "%#{params[:search]}%"]
                        )

【问题讨论】:

    标签: mysql ruby-on-rails postgresql heroku


    【解决方案1】:

    也遇到了这个问题。 Postgres 对 LIKE 运算符区分大小写,所以这是我在项目中所做的。另外,我不喜欢在本地运行 postgres,所以我在开发中使用 LIKE (mysql/sqlite) 和在生产中使用 ILIKE (postgres) 运行它。 ILIKE 是“不区分大小写的”

    /config/environment.rb

      DATABASE_OPERATOR = {
        :like_operator => "LIKE"
      }
    

    /config/environments/production.rb

      DATABASE_OPERATOR = {
        :like_operator => 'ILIKE' #postgres awfulness
      }
    

    查询

    @students = Student.find(:all, :conditions => ['(concat(first_name, " ", last_name) #{DATABASE_OPERATOR[:like_operator]} ?) OR (concat(first_name, " ", middle_names, " ", last_name) #{DATABASE_OPERATOR[:like_operator]} ?)', "%#{params[:search]}%", "%#{params[:search]}%"])
    

    【讨论】:

    • 这是怎么回事?只是不一样。
    • 嘿,我可以有意见。就是这样:如果大多数其他数据库都对“like”进行不区分大小写的搜索,那就继续吧。如果你真的想要区分大小写,让我用一个特殊的命令来搜索。
    • 虽然这对我的问题没有帮助,但很高兴知道。我将使用 ILIKE
    • 谢谢你 - 救了我的培根!
    【解决方案2】:

    使用管道 ||而不是 CONCAT,这是标准 SQL:

    @students = Student.find(:all, :conditions => ['(first_name || last_name LIKE ?) OR (first_name || middle_names || last_name LIKE ?)', "%#{params[:search]}%", "%#{params[:search]}%"])
    

    还要检查你的引号,你需要单引号 ' 用于字符串,双引号 " 用于数据库对象。MySQL 接受这两者,取决于配置,其他数据库只接受标准。

    【讨论】:

    • (first_name || last_name LIKE ?) 将只返回%search% 存在于last_name 中的行。
    • 根据一些论坛帖子 || 的行为在 mySQL 中是非标准的,在 pg 中是 concat。
    【解决方案3】:

    使用concat() 毫无意义。 @Frank 的答案很接近,但逻辑被打破了。

    where (first_name || last_name LIKE ?) 计算结果为

    “其中first_name 计算结果为true 其中last_name 包含搜索词”

    这应该会得到预期的结果

    Student.all(
      :conditions => ["
        first_name like :search ||
        last_name like :search  ||
        middle_names like :search
        ",
        {:search => "%#{params[:search]}%"}
      ]
    )
    

    这将匹配students 表中名称中任何部分包含params[:search] 的所有行。

    【讨论】:

    • 什么,但是如果查询字符串包含,例如他们的名字和姓氏。在这种情况下,我的 mySQL 代码会找到它们,但你的会失败。
    【解决方案4】:

    使用以下

    Student.find(:all, 
                      :conditions =>["(concat(first_name, ' ', last_name) LIKE :text) OR
                                      (concat(first_name, ' ', middle_names, ' ', last_name) LIKE :text)",
                                     {:text=>"%#{params[:search]}%"]
                            )
    

    【讨论】:

    • 你到底买了什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    • 1970-01-01
    • 2019-06-11
    • 2015-10-29
    相关资源
    最近更新 更多