テーブル構造
こんな感じのテーブルがあるとします。
$table = $this->table('posts'); $table->addColumn('title', 'string') ->addColumn('description', 'text') ->addColumn('body', 'text') ->addColumn('published', 'boolean') ->addColumn('created', 'datetime') ->addColumn('modified', 'datetime') ->create();
一覧を取得
すべてのデータを取得したいときはfind
の引数にall
を指定します。
$this->Posts->find('all');
引数のall
はデフォルト値なので指定しないでも同じ結果になります。
$this->Posts->find();
キーワード完全一致
titleが指定したキーワードと一致したものを検索したいときはwhere
で条件指定します。
引数は連想配列でkeyにカラム名、valueに検索ワードを指定します。
$this->Posts->find()->where(['title' => '検索ワード']);
キーワード部分一致
titleに指定したキーワードが含まれたものを検索したいときはLIKE
検索を使います。
配列のkeyは「カラム名 LIKE」という形になります。
「%検索ワード」の場合は最後に「検索ワード」で終わる条件になり、「%検索ワード%」はどこかに「検索ワード」が含まれているかという条件です。
$this->Posts->find()->where(['title LIKE' => '%検索ワード%']);
複数条件を指定
titleのLIKE
検索と、publishedがtrueの複数の条件で検索したい場合は、where
に配列で追加します。
$this->Posts->find()->where(['title LIKE' => '%検索ワード%', 'published' => true]);
andWhere
で繋げても同じ結果になります。
$this->Posts->find()->where(['title LIKE' => '%検索ワード%'])->andWhere(['published' => true]);
複数条件(OR)検索
先ほどは複数の条件がマッチしたレコードだけ取得しました。
これをAND検索というのですが、今度はOR検索というのを試してみます。
例えばtitle
にいずれかのキーワードが含むというのを条件にしてみましょう。
$this->Posts->find() ->where([ 'OR' => [ ['title LIKE' => '%検索ワード1%'], ['title LIKE' => '%検索ワード2%'] ] ]);
指定日以降の検索
指定日以降を検索したい場合もwhere
を使用します。
条件符号も付与することで指定した値以降のレコードを取得できます。
createが2020年4月28日以降を取得したい場合は次のようになります。
$this->Posts->find()->where(['created >' => '2020-04-28']);
指定した日の検索
createカラムはdatatime型ですが、日付で検索したい場合はDATEフォーマットに変換することでマッチさせることができます。
createが2020年4月28日のデータを取得したい場合は次のようになります。
$this->Posts->find()->where(['DATE(created)' => '2020-04-28']);
少し長いですがbetween
使う方法もあります。
$this->Posts->find()->where(function($exp) { return $exp->between('created', '2020-04-28', '2020-04-29'); });
指定日から指定日までの範囲検索
全項目ですでに解説しましたが、指定日から指定日までの範囲検索するにはbetween
を使用します。
createが2020年4月28日から31日のデータを取得したい場合は次のようになります。
$this->Posts->find()->where(function($exp) { return $exp->between('created', '2020-04-28', '2020-05-01'); });
動的ファインダー
「findByカラム名」で検索することもできます。
例えばpublishedがtrueのものを取得したい場合、whereを使用すると下記のようになります。
$this->Posts->find()->where(['published' => false]);
動的ファインダーを使用すると下記のように短く書くことができます。
$this->Posts->findByPublished(true);
件数を指定
ここからは取得条件の設定になります。
3件だけなど、取得件数を指定する場合はlimit
を使用します。
$this->Posts->find()->limit(3);
並び順を指定
デフォルトではプライマリキーの昇順で表示されますが、order
を指定することで、カラムの指定や並び方法を変更することができます。
createを降順で並び替えしたい場合は次のようになります。
$this->Posts->find()->order(['created' => 'desc']);
カラムを指定
カラム数が多い場合や情報量が多いカラムがある場合はselect
で取得するカラムを指定することができます。
$this->Posts->find()->select(['id','title','created']);
リレーションの検索
テーブル同士で結合(リレーション)するということはよくあると思います。
モデルで設定しただけでは
Userテーブルと繋げたい場合。
$this->Posts->find()->contain(['Users']);
2つのテーブルで同じ名前のカラムがある場合、使用する場合はカラム名も指定する必要があります。
$this->Posts->find()->contain(['Users'])->where(['Posts.created >' => '2020-04-20']);
belongsToManyでリレーション先で検索
よくあるPostsとTagsが多対多の関係でタグIDで検索したいときとか。
$this->Posts->find() ->matching( 'Tags', function (Query $q) use ($id){ return $q->where(['Tags.id' => $id]); } );
この記事の動画(Youtube)版はこちら!