![](/img/trans.png)
[英]PHP to select records from one table based on match of value contained in string in second table in 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.