J'ai la requête SQL suivante à la base de données:
$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();
Comment réécrire les lignes avec CASE, WHEN ... THEN ... au "format" basé sur Joomla avec un filtrage comme:
$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');
Je vais recommander cette syntaxe:
$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()
est l'alias de quoteName()
et est utilisé pour encapsuler les noms de tables, les noms de colonnes et leurs alias. Lorsque vous affectez un alias de table, écrivez-le simplement en tant que deuxième paramètre dans qn()
$category_id
Dans une clause WHERE
, car j'estime qu'elle est plus appropriée et plus facile à lire.getQuery()
- parce que cela peut être fait.(int)
Est appliqué à $category_id
Par mesure de sécurité.try-catch()
sont pratiques lors du débogage, il suffit de ne jamais afficher les requêtes ou les erreurs sur votre site actif.Avec un category_id de 1, la requête rendue ressemble à ceci: (J'ai mis la valeur dump()
en onglet)
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`
Et enfin, voici le db-fiddle pour prouver que cela fonctionne.
$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'));
Il n'y a pas de fonction basée sur Joomla pour la construction cas/when/then , vous devez utiliser une sélection simple avec mysql déclarations de cas en elle.
$query->select("(CASE ...) as final_price");
Jetez un œil à API JDatabaseQuery pour obtenir la liste complète des fonctions Joomla disponibles dans la base de données.