"SELECT *, ((ACOS(SIN($lat * PI() / 180) * SIN(latitude * PI() / 180) + COS(78 * PI() / 180) * COS(latitude * PI() / 180) * COS((87 - longitude) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS distance "
. "FROM `#__content` AS `b` "
. "RIGHT JOIN `#__jreviews_content` AS `a` ON (`a`.`contentid` = `b`.`id`) "
. "LEFT JOIN `#__categories` AS `c` ON (`b`.`catid` = `c`.`id`) "
. "LEFT JOIN `#__jreviews_media` AS `m` ON (`m`.`listing_id` = `b`.`id` AND `m`.`main_media` = 1 AND `m`.`media_type` = 'photo') "
. "WHERE 1 = 1 AND (`c`.`title` LIKE '%Stores%' OR `c`.`title` LIKE '%Dining%' OR `c`.`title` LIKE '%Events%') AND `a`.`jr_latitude`<> 0.0000000 AND `c`.`title`<> 'Archives' "
. "HAVING distance<='50' "
. "ORDER BY distance ASC"
J'ai réussi à écrire la requête avec Query Object
sans HAVING
$query->select(array('*', '((ACOS(SIN($lat * PI() / 180) * SIN(latitude * PI() / 180) + COS(78 * PI() / 180) * COS(latitude * PI() / 180) * COS((87 - longitude) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS distance'))
->from($content)
->join('RIGHT', $jreviews_content . ' ON (' . $db->quoteName('a.contentid') . ' = ' . $db->quoteName('b.id') . ')')
->join('LEFT', $categories . ' ON (' . $db->quoteName('b.catid') . ' = ' . $db->quoteName('c.id') . ')')
->join('LEFT', $media . ' ON (' . $db->quoteName('m.listing_id') . ' = ' . $db->quoteName('b.id') . ' AND ' . $db->quoteName('m.main_media') . ' = 1 AND ' . $db->quoteName('m.media_type') . ' = "photo")')
->where($conditions);
S'il vous plaît, aidez-moi, s'il vous plaît, à écrire le HAVING
dans ce Query Object
Si vous utilisez la clause having
sans Group_by, il agira exactement comme la clause where.
La classe JDatabaseQuery fournit une méthode pour avoir une clause.
Essaye ça
$query->having('distance <=50');
J'aimerais ajouter quelques raffinements à la requête publiée ...
1 = 1
!=
lors de la comparaison d’une chaîne, alors que <>
est plus approprié lors de la comparaison de valeurs numériques.$lat
dans SELECT doit être transtypé en tant que float pour de meilleures pratiques de sécurité.a
et descendre à partir de là au lieu d'utiliser un ordre cassé.Je vais aveuglément faire confiance à vos calculs et je ne peux pas être tout à fait sûr de la justesse de vos choix de JOIN sans avoir quelques exemples de données et connaître le résultat souhaité. Je laisserai donc ces aspects de côté.
Nouveau RAW SQL:
SELECT *, (ACOS(SIN($lat * PI() / 180) * SIN(latitude * PI() / 180) + COS(78 * PI() / 180) * COS(latitude * PI() / 180) * COS((87 - longitude) * PI() / 180)) * 180 / PI()) * 60 * 1.1515 AS distance
FROM #__content a
RIGHT JOIN #__jreviews_content b ON b.contentid = a.id
LEFT JOIN #__categories c ON a.catid = c.id
LEFT JOIN #__jreviews_media d ON d.listing_id = a.id
WHERE d.main_media = 1
AND d.media_type = 'photo'
AND c.title != 'Archives'
AND b.jr_latitude <> 0.0000000
AND c.title REGEXP 'Stores|Dining|Events'
HAVING distance <= 50
ORDER BY distance
HAVING
est nécessaire ici car l'alias de colonne distance
n'est pas encore disponible lorsque la logique WHERE
est implémentée.
équivalent PHP/Joomla (non testé):
$query = $db->getQuery(true)
->select([
"*",
"(ACOS(SIN(" . (float)$lat . " * PI() / 180) * SIN(latitude * PI() / 180) + COS(78 * PI() / 180) * COS(latitude * PI() / 180) * COS((87 - longitude) * PI() / 180)) * 180 / PI()) * 60 * 1.1515 AS distance"
])
->from("#__content a")
->rightJoin("#__jreviews_content b ON b.contentid = a.id")
->leftJoin("#__categories c ON a.catid = c.id")
->leftJoin("#__jreviews_media d ON d.listing_id = a.id")
->where([
"d.main_media = 1",
"d.media_type = " . $db->q("photo"),
"c.title != " . $db->q("Archives"),
"b.jr_latitude <> 0.0000000",
"c.title REGEXP " . $db->q("Stores|Dining|Events")
])
->having("distance <= 50")
->order("distance");