質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

3回答

7159閲覧

【Rails, MySQL】 Limitを指定しつつ条件に当てはまる件数を取得したい

n_kitamura

総合スコア17

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2017/12/06 16:51

編集2017/12/07 01:58

「記事」と「コメント」のようなhas_manyな関係のテーブルがあるとします。
ここから、記事本文と、子のコメント本文両方を対象にしたLIKE検索を行おうとしています。

articles

idtext
1あああ

comments

idarticle_idtext
11いいい
21ううう

検索自体は、以下のようにGROUP_CONCATを使うことで実現できました。

ruby

1 articles = Article 2 .joins(:comments) 3 .group("comments.article_id") 4 .having("CONCAT(articles.text, GROUP_CONCAT(comments.text)) like '%検索ワード%'") 5 .limit(10).offset(10) 6

加えて、limit,offsetを考慮しない「検索条件にあてはまる全件数」をカウントする必要があります。

そこで、こちらの記事を参考に、

articles.except(:limit, :offset).count

などと試したのですが、groupやhavingがある場合(?)クエリエラーとなってしまいうまくいきません。

何かいい方法はないでしょうか?

そもそもGROUP_CONCATで検索している部分から否定して頂いても構いません。

何卒よろしくお願い致します。


追記:

.countで出力されたSQLは以下のような感じで、

SELECT COUNT(*) AS count_all, comments.article_id AS comments_article_id FROM `articles` INNER JOIN `comments` ON `comments`.`article_id` = `articles`.`id` GROUP BY comments.article_id HAVING (CONCAT(articles.description, GROUP_CONCAT(comments.description)) like '%ワード%')

1054 - Unknown column 'articles.description' in 'having clause'
となってしまいます。

  • このエラーが出るのはカウント時のみで、selectを「articles.*」に置き換えると問題なく通ります。
  • HavingをWhereに置き換えるとGROUP_CONCATが使えなくなってしまいます。
  • エラー箇所であるarticles.descriptionを消すとクエリは通るのですが、当然記事本文が検索対象に含まれなくなります。
  • そもそも、SELECTでcount_allのほかにcomments_article_idも指定されている理由もわかりません…。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

having とかはよくわかりませんが,最初のコードで正しく articles が得られるのであれば,

rb

1articles = Article 2 .joins(:comments) 3 .group("comments.article_id") 4 .having("CONCAT(articles.text, GROUP_CONCAT(comments.text)) like '%検索ワード%'") 5article_count = articles.count 6articles = articles.limit(10).offset(10)

でいけませんかね。

投稿2017/12/06 23:22

scivola

総合スコア2108

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

n_kitamura

2017/12/07 01:58

ご回答ありがとうございます! 試してみたのですが、やはりクエリエラーとなってしまいました。 このエラーについて補足させて頂きました。
guest

0

ベストアンサー

検索条件にあてはまる全件数とは

  • articles
aidtext
1あああ
2かかか
3さささ
  • comments
cidaidtext
11いいい
21うういいいうう
31ううう
42ききき
52くくいいいくく
63ししし

だったときに、「いいい」を検索した時
ヒットする「aid=1:あああ」と「aid=2:かかか」の2件がほしいのか
cid=1、2、5の3件がほしいのでしょうか?

前者なら

SQL

1SELECT COUNT(DISTINCT aid) FROM comments 2WHERE text LIKE '%いいい%';

後者なら単純に

SQL

1SELECT COUNT(*) FROM comments 2WHERE text LIKE '%いいい%';

投稿2017/12/07 00:37

yambejp

総合スコア114779

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

n_kitamura

2017/12/07 02:25

説明不足で申し訳ありません。前者です。 なるほど、comment側を対象にarticle本文をjoinして検索すればGROUP_CONCATが不要になるんですね。 ありがとうございます。
guest

0

scivolaさんの方法に似ていますが、単純にlengthで長さを取ることでも実現できました。

ruby

1articles = Article 2 .joins() 3 .group() 4 .having() 5article_count = articles.length 6articles = articles.limit(10).offset(10)

しかし、lengthを書いた時点でlimitのないクエリが実行されるようで、無駄にメモリが消費されているようにも思えます…。

投稿2017/12/07 02:53

n_kitamura

総合スコア17

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問