データベースへの次のSQLクエリがあります。
$jinput = JFactory::getApplication()->input;
$category_id = $jinput->get('virtuemart_category_id');
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query = 'SELECT b.`virtuemart_product_id`,
(CASE
WHEN b.`product_override_price` > 0 THEN b.`product_override_price`
WHEN b.`product_discount_id` > 0 THEN b.`product_price` - (b.`product_discount_id` * b.`product_price` / 100)
WHEN b.`product_price` < 1 THEN 1
ELSE b.`product_price`
END) as final_price
FROM #__virtuemart_product_categories as a
LEFT JOIN #__virtuemart_product_prices as b ON b.`virtuemart_product_id` = a.`virtuemart_product_id`
AND `virtuemart_category_id` = '.$category_id.'
ORDER BY final_price ASC';
$db->setQuery($query);
$rows = $db->loadObjectList();
CASE、WHEN ... THEN ...で行をJoomlaベースの「フォーマット」に書き換える方法:
$query->select('a.virtuemart_product_id');
$query->from('#__virtuemart_product_categories AS a');
$query->where($db->quoteName('virtuemart_category_id')." = ".$db->quote($category_id));
... // ???
$query->join('LEFT', '#__virtuemart_...');
$query->order('final_price ASC');
この構文をお勧めします:
_$db = JFactory::getDBO();
try {
$query = $db->getQuery(true)
->select(
array(
$db->qn('b.virtuemart_product_id'),
"CASE WHEN " . $db->qn('b.product_override_price') . " > 0" .
" THEN " . $db->qn('b.product_override_price') .
" WHEN " . $db->qn('b.product_discount_id') . " > 0" .
" THEN " . $db->qn('b.product_price') . " - (" . $db->qn('b.product_discount_id') . " * " . $db->qn('b.product_price') . " / 100)" .
" WHEN " . $db->qn('b.product_price') . " < 1" .
" THEN 1" .
" ELSE " . $db->qn('b.product_price') .
" END AS " . $db->qn('final_price')
)
)
->from($db->qn('#__virtuemart_product_categories', 'a'))
->innerJoin($db->qn('#__virtuemart_product_prices', 'b') . " ON " . $db->qn('b.virtuemart_product_id') . " = " . $db->qn('a.virtuemart_product_id'))
->where($db->qn('a.virtuemart_category_id') . " = " . (int)$category_id)
->order($db->qn('final_price'));
echo $query->dump(); // of course, don't do this on your live/public site
$db->setQuery($query);
echo "<pre>";
var_export($db->loadObjectList());
echo "</pre>";
} catch (Exception $e) {
echo "<div>", $e->getMessage(), "</div>"; // of course, don't do this on your live/public site
}
_
qn()
はquoteName()
のエイリアスであり、テーブル名、列名、およびそれらのエイリアスをバックティックラップするために使用されます。テーブルエイリアスを割り当てる場合は、qn()
の2番目のパラメータとして書き込みます。$category_id
_をWHERE
句に書き込みました-より適切で読みやすいと思うからです。getQuery()
からメソッドをチェーンすることを好みます-実行できるからです。(int)
_は、セキュリティ上の予防措置として_$category_id
_に適用されます。try-catch()
ブロックはデバッグ時に便利です。ライブサイトにクエリやエラーを表示しないでください。Category_idが1の場合、レンダリングされたクエリは次のようになります(私はdump()
値にタブを付けました)
_SELECT `b`.`virtuemart_product_id`,
CASE WHEN `b`.`product_override_price` > 0 THEN `b`.`product_override_price`
WHEN `b`.`product_discount_id` > 0 THEN `b`.`product_price` - (`b`.`product_discount_id` * `b`.`product_price` / 100)
WHEN `b`.`product_price` < 1 THEN 1 ELSE `b`.`product_price`
END AS `final_price`
FROM `vwxyz_virtuemart_product_categories` AS `a`
INNER JOIN `vwxyz_virtuemart_product_prices` AS `b` ON `b`.`virtuemart_product_id` = `a`.`virtuemart_product_id`
WHERE `a`.`virtuemart_category_id` = 1
ORDER BY `final_price`
_
そして最後に、これが動作することを証明する db-fiddle です。
$query->select('a.virtuemart_product_id')
->from('#__virtuemart_product_categories AS a')
->select('(CASE WHEN '.$db->qn('b.product_override_price').' > 0
THEN '.$db->qn('b.product_override_price').
' WHEN '.$db->qn('b.product_discount_id').' > 0
THEN '.$db->qn('b.product_price').' - ('.$db->qn('b.product_discount_id').' * '.$db->qn('b.product_price').' / 100)
WHEN '.$db->qn('b.product_price').' < 1
THEN 1 ELSE '.$db->qn('b.product_price').' END)
as '.$db->qn('final_price'));
case/when/then構成のJoomlaベースの関数はありません。mysqlで単純な選択を使用する必要がありますその中のcaseステートメント。
$query->select("(CASE ...) as final_price");
利用可能なデータベースJoomla関数の完全なリストについては、 JDatabaseQuery API を参照してください。