LoginSignup
0
0

More than 1 year has passed since last update.

Laravel withCount ある商品の購入人数を知りたい時(同じユーザーが複数回購入しても1回でカウントする)

Last updated at Posted at 2021-11-08

はじめに

題名の通りですが、ある商品の購入者数をカウントしたい場合があるとします。
同じ人が何回購入しても、売れた個数を1個としてカウントしたい場合の処理を紹介します。
ランキングを表示する際に同じ人が何度も購入してた場合、その購入数を1回でカウントしたい時に実装しました。

目次

  1. テーブル構成
  2. 商品のランキング表示処理
  3. 試してダメだった事
  4. 最後に

テーブル構成

まずはテーブル構成ですが、goods、payments、usersテーブルがあるとします。
リレーションの処理はこちらでは省略しますので、自身で書いて下さい。

【テーブル構成】
users → ユーザー情報
goods → 商品の情報
payments → 購入履歴情報 (中間テーブル)
paymentsは中間テーブルなので、goods_idとuser_idを持っています。

商品のランキング表示処理

・withCountで、ある商品のグッズの購入数を取得できます。
同じユーザーが複数回購入しても1回でカウントする為にdistinctを用いています。
 distinct → 重複するuser_idを1つにまとめる。
・最後にorderByで購入者が多い順に並べ替えています。

// GoodsController.php

// 商品ランキングページを表示する処理
public function index()
{
    // グッズの購入人数を取得して、人数順に並び替える
    $goods_ranking = Goods::getPaymentsCount()->orderBy('payments_count', 'DESC');

    return view('user.index', ['goods_ranking' => $goods_ranking]);
}
// app/Models/Goods.php

public function scopeGetPaymentsCount($query)
{
    // withCountでリレーション先のそのグッズの購入数を取得する
    return $query->withCount(['payments' => function ($query) {
                // distinctで重複する。user_idを1つにまとめる
        $query->select(DB::raw('count(distinct(`user_id`))'));
    }]);
}

試してダメだった事

クエリビルダーのgroupByとwithCountを組み合わせて取得してみましたが、エラーが出て、うまく取得できませんでした。
いけそうでいけないです・・・良い方法があれば教えて頂きたいです!!

public function scopeGetPaymentsCount($query)
{
   // withCountでリレーション先のそのグッズの購入数を取得する
       return $query->withCount(['payments' => function ($query) {
              // groupByで重複する。user_idを1つにまとめる・・・事が出来ませんでした・・・
           $query->groupBy('user_id');
       }]);
}

最後に

ちなみにクエリビルダーのjoinとgroupByを組み合わせても実装自体は可能です。
経験が浅いので、良い方法があれば是非教えて下さい!!
ここまで読んで頂き、ありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0