Doctrineのsubquery文やjoinを使ったQueryBuilder、DQLの書き方が分かりません
SQL文だと簡単に書けるものが、DoctrineのqueryBuilderやDQLだとどうしても書けなくて2日も悩んでおります。
dtb_customerとdtb_orderがOneToManyの関係にあって、dtb_customer.id = dtb_order.customer_idになっております。
やりたいことは顧客検索欄で購入件数の範囲指定できるようにすることです。
これをSQLで書くと以下になります。
SQL
1-- subqueryを使った場合 2select * FROM onestopinnov_sid.dtb_customer as c where c.id IN ( 3 select customer_id from onestopinnov_sid.dtb_order group by customer_id, order_status_id having count(customer_id) > 0 AND order_status_id IN ([購入完了ステータスIDをここに]) 4); 5-- joinを使った場合 6select c.id FROM onestopinnov_sid.dtb_customer as c 7 join (select customer_id from onestopinnov_sid.dtb_order group by customer_id, order_status_id having count(customer_id) > 0 AND order_status_id IN ([購入完了ステータスIDをここに])) as o 8 ON c.id = o.customer_id 9 where 10 c.id = o.customer_id 11;
(order_status_idは購入が完了してある注文だけを抽出するためのものです。)
でもこれをquerybuilderで作ろうとするとどうしてもうまくいきません。。。
PHP
1$qb = $this->createQueryBuilder('c') 2 ->select('c'); 3[中略] 4// buy_times 5if (isset($searchData['buy_times_start']) && StringUtil::isNotBlank($searchData['buy_times_start'])) { 6 $qb 7 ->leftJoin('c.Orders', 'o') 8 ->andWhere('COUNT(o.Customer) >= :buy_times_start') 9 ->setParameter('buy_times_start', $searchData['buy_times_start']); 10}
あとDQLでサブクエリを使ってやってみようともしたのですが、これもうまくいきません、、、
(気になる方いらっしゃいましたら書いて失敗したDQLも貼ります)
下記がエラー文です。
bash
1["An exception occurred while executing 'SELECT count(DISTINCT d0_.id) AS sclr_0 FROM dtb_customer d0_ LEFT JOIN dtb_order d1_ ON d0_.id = d1_.customer_id AND d1_.discriminator_type IN ('order') WHERE (COUNT(d1_.customer_id) >= ? AND d0_.customer_status_id IN (?, ?) AND d0_.cognito_flg IN (?, ?) AND d0_.singup_point_flg IN (?, ?)) AND d0_.discriminator_type IN ('customer')' with params [1, 1, 2, true, false, true, false]
以下が二つのEntityの該当のプロパティです。
CustomerのEntity
PHP
1/** 2* @var \Doctrine\Common\Collections\Collection 3* 4* @ORM\OneToMany(targetEntity="Eccube\Entity\Order", mappedBy="Customer") 5*/ 6private $Orders;
OrderのEntity
PHP
1/** 2* @var \Eccube\Entity\Customer 3* 4* @ORM\ManyToOne(targetEntity="Eccube\Entity\Customer", inversedBy="Orders") 5* @ORM\JoinColumns({ 6* @ORM\JoinColumn(name="customer_id", referencedColumnName="id") 7* }) 8*/ 9private $Customer;
ちなみにdtb_customerテーブルには実はbuy_times_start
、buy_times_end
とかlast_buy_start
、last_buy_end
などののカラムが既にあります。
でもこれだと注文に何か更新があるたびにdtb_customerも直さなければいけなくて、なるべくやりたい方法ではないのです。
この考え方はおかしいのでしょうか?
できれば検索の時だけ二つのテーブルをうまく結合したやり方でやりたいのですが、Doctrineの書き方がどうしても分からなくてみなさんの知恵をお借りしたいのです。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。