How can I convert conditional aggregation mysql to laravel query?

How can I convert conditional aggregation mysql to laravel query?



My sql query like this :


SELECT a.number, a.description,
MAX(CASE WHEN b.attribute_code = 'brand' then b.attribute_value END) as brand,
MAX(CASE WHEN b.attribute_code = 'model' then b.attribute_value END) as model,
MAX(CASE WHEN b.attribute_code = 'category' then b.attribute_value END) as category,
MAX(CASE WHEN b.attribute_code = 'subcategory' then b.attribute_value END) as subcategory
FROM items a JOIN
attr_maps b
ON b.number = a.number
GROUP BY a.number, a.description
HAVING brand = 'honda'



If the query executed, it works



I want to convert the query sql to laravel query



I try like this :


$query = Item::selectRaw("a.number, a.description, MAX(CASE WHEN b.attribute_code = 'brand' then b.attribute_value END) as brand, MAX(CASE WHEN b.attribute_code = 'model' then b.attribute_value END) as model, MAX(CASE WHEN b.attribute_code = 'category' then b.attribute_value END) as category, MAX(CASE WHEN b.attribute_code = 'subcategory' then b.attribute_value END) as subcategory")
->from('items as a')
->join('attr_maps as b','b.number','=','a.number')
->groupBy('a.number');
foreach($param as $key => $value)
$query = $query->havingRaw("$key = $value");

$query = $query->orderBy('description')
->paginate(10);
return $query;



It the query executed, there exist error like this :


SQLSTATE[42S22]: Column not found: 1054 Unknown column 'brand' in 'having clause' (SQL: select count(*) as aggregate from `items` as `a` inner join `attr_maps` as `b` on `b`.`no` = `a`.`no` group by `a`.`no` having brand = honda)



How can I solve the error?



Note



The result of echo '<pre>';print_r($param);echo '</pre>';die(); :


echo '<pre>';print_r($param);echo '</pre>';die();


Array
(
[brand] => honda
[model] => pcx
[category] => test1
[subcategory] => test2
)



Update



I had find a solution. It like this :


public function list($param)

$brand = "MAX(CASE WHEN b.attribute_code = 'brand' then b.attribute_value END)";
$model = "MAX(CASE WHEN b.attribute_code = 'model' then b.attribute_value END)";
$category = "MAX(CASE WHEN b.attribute_code = 'category' then b.attribute_value END)";
$subcategory = "MAX(CASE WHEN b.attribute_code = 'subcategory' then b.attribute_value END)";

$query = Item::selectRaw("a.number, a.description, $brand as brand, $model as model, $category as category, $subcategory as subcategory")
->from('items as a')
->join('item_attr_maps as b','b.number','=','a.number')
->groupBy('a.number');

foreach($param as $key => $value)
$query = $query->havingRaw("$$key = ?", [$value]);


$query = $query->orderBy('description')
->paginate(self::ITEM_PER_PAGE);

return $query;




2 Answers
2



You have to supply the aggregate function in having clause, we can reuse the same one that we have in select like this


aggregate


$brand = "MAX(CASE WHEN b.attribute_code = 'brand' then b.attribute_value END)";

$model = "MAX(CASE WHEN b.attribute_code = 'model' then b.attribute_value END)";

$category = "MAX(CASE WHEN b.attribute_code = 'category' then b.attribute_value END)";

$subcategory = "MAX(CASE WHEN b.attribute_code = 'subcategory' then b.attribute_value END)";

$brandName = 'honda';

$query = Item::selectRaw("a.number, a.description, $brand as brand, $model as model, $category as category, $subcategory as subcategory")
->from('items as a')
->join('attr_maps as b','b.number','=','a.number')
->groupBy('a.number')
->havingRaw("$brand = ?", [$brandName])
->orderBy('description')
->paginate(10);

return $query;



EDIT: After comments



You can execute for each params like this


$query = Item::selectRaw("a.number, a.description, $brand as brand, $model as model, $category as category, $subcategory as subcategory")
->from('items as a')
->join('attr_maps as b','b.number','=','a.number')
->groupBy('a.number')
->orderBy('description');

foreach($param as $key => $value)
$query = $query->havingRaw("$$key = ?", [$value]);


$results = $query->paginate(10);

return $results;






There exist error like this : SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '} = ?' at line 1 (SQL: select count(*) as aggregate from items` as a inner join attr_maps as b on b.number = a.number group by a.number having $brand = honda)`

– Success Man
Sep 9 '18 at 5:54


SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '} = ?' at line 1 (SQL: select count(*) as aggregate from


a


attr_maps


b


b


number


a


number


a


number






Okay, thanks. Please see my question. I had update it. Actually the having raw is dynamic

– Success Man
Sep 9 '18 at 6:12






I'm still confused to implement it if the brand is dynamic

– Success Man
Sep 9 '18 at 6:14






There exist error like this : SQLSTATE[42S22]: Column not found: 1054 Unknown column 'brand' in 'having clause' (SQL: select count(*) as aggregate from items` as a inner join attr_maps as b on b.no = a.no group by a.no having brand = 'honda')`

– Success Man
Sep 9 '18 at 7:31


SQLSTATE[42S22]: Column not found: 1054 Unknown column 'brand' in 'having clause' (SQL: select count(*) as aggregate from


a


attr_maps


b


b


no


a


no


a


no






my mistake it should be $$key in havingRaw. updated answer

– rkj
Sep 9 '18 at 7:39


$$key


havingRaw



Hope this helps you -


$perPage = $request->input("per_page", 10);
$page = $request->input("page", 1);
$skip = $page * $perPage;
if($take < 1) $take = 1;
if($skip < 0) $skip = 0;

$basicQuery =DB::select(DB::raw("SELECT a.number, a.description,
MAX(CASE WHEN b.attribute_code = 'brand' then b.attribute_value END) as brand,
MAX(CASE WHEN b.attribute_code = 'model' then b.attribute_value END) as model,
MAX(CASE WHEN b.attribute_code = 'category' then b.attribute_value END) as category,
MAX(CASE WHEN b.attribute_code = 'subcategory' then b.attribute_value END) as subcategory
FROM items a JOIN
attr_maps b
ON b.number = a.number
GROUP BY a.number, a.description
HAVING brand = 'honda'"
));
$totalCount = $basicQuery->count();
$results = $basicQuery
->take($perPage) // can be 10
->skip($skip)
->get();
$paginator = new IlluminatePaginationLengthAwarePaginator($results, $totalCount, $take, $page);
return $paginator;






There exist error : Call to a member function paginate() on array

– Success Man
Sep 9 '18 at 7:38


Call to a member function paginate() on array






Okay thanks. I will check your code

– Success Man
Sep 9 '18 at 7:57



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

ャフサォクコ ケウ,コ,ワ メ,ロスョノ゙,クネ,フムカヤヲニ,エコ゚ツ ウイオン゙ケワサネォキモュキォウイノンコチ゚メヌナイゥフュ,カヒウネェ ネ,ホノケ,ムュキ ッボーミュハ,チ ツス ィ メウイマヤ,゙ウチ ヅ ロ,ォジヌェ ャヌット ェ,マャ,チナエヒネソキツテ トホヲヲミーァ

Node.js puppeteer - Use values from array in a loop to cycle through pages