簡體   English   中英

Select 表中列值包含在字符串中的記錄(帶有 ActiveRecord 的 mysql)

[英]Select records from table where column value is contained in string (mysql with ActiveRecord)

假設我有一個名為books的表,其中有一列名為keyword 假設我還有一個名為words的字符串。

我想要 select 列keyword包含在words中的books的所有記錄。 我可以直接在 mysql 中使用 LIKE 來執行此操作。如果有人可以幫助我了解語法,我正在嘗試將其轉換為 Rails 應用程序的 ActiveRecord 查詢。

棘手的部分是我想找到列值包含在我的字符串中的記錄,而不是相反。 與這個問題非常相似,只是我需要將其翻譯成 ActiveRecord。 SQL - 查詢字符串是否包含 Column 中的部分值

這是我正在嘗試翻譯的有效 sql 查詢。

SELECT * FROM books WHERE "new science fiction" LIKE CONCAT('%',keyword,'%');

在上面的例子中“new science fiction”就是字符串words

假設我有 3 book記錄。 book1 有關鍵字“science”,book2 有關鍵字“fiction”,book3 有關鍵字“other”。 我的上述查詢將返回記錄 book1 和 book2。 因為 'science' 和 'fiction' words在字符串 'new science fiction' 中。

我的 SQL 查詢有效,但我不知道如何使用 ActiveRecord 中的Book.where語句進行查詢。

我認為你最好的選擇是:

Book.where(keyword: words.split)

這將導致

SELECT * FROM books WHERE books.keyword IN ('new', 'science', 'fiction')

這將返回相同的記錄。

注意:根據您的 RDBMS, IN()可能區分大小寫。 為了避免這種情況,我們可以將上面的更改為

Book.where(Book.arel_table[:keyword].lower.in(words.downcase.split))

這將導致

SELECT * FROM books WHERE LOWER(books.keyword) IN ('new', 'science', 'fiction')

如果你真的想要 go 與你現在的方式,我們可以一起破解它如下:

Book.where(
  Arel::Nodes::UnaryOperation.new(nil,Arel::Nodes.build_quoted(words))
    .matches(
      Arel::Nodes::NamedFunction.new(
       'CONCAT', 
       [Arel.sql("'%'"),Book.arel_table[:keyword],Arel.sql("'%'")])
))

這將產生所需的 SQL,同時仍然利用 Arel 和連接適配器提供的 escaping。

區分大小寫在這里不是問題,因為Arel::Predications#matches默認使用case_sensitive = false意味着 Postgres 將使用ILIKE而不是LIKE

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM