it-swarm.com.de

Joomla 2.5, wie man "HAVING" mit Query Object benutzt

"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"

Ich habe es geschafft, die Abfrage mit Query Object Ohne HAVING zu schreiben.

$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);

Bitte helfen Sie mir, das HAVING in dieses Query Object Zu schreiben.

2
Siva.G ツ

Wenn Sie die having -Klausel ohne group_by verwenden, verhält es sich wie die where-Klausel.

Die JDatabaseQuery-Klasse stellt eine Methode für die having-Klausel bereit.

Versuche dies

$query->having('distance <=50');
4
Nick

Ich möchte der geposteten Abfrage einige Verbesserungen hinzufügen ...

  • Während dies gültig ist, empfehle ich, die bedingten Filter in der WHERE-Klausel im Vergleich zum ON-Ausdruck des JOIN zu erstellen. Das Lesen auf diese Weise ist sauberer.
  • Anstatt 3 separate LIKE-Bedingungen zu schreiben, ist es kürzer, eine einzelne REGEXP-Bedingung zu schreiben, in der die 3 ausgewählten Teilzeichenfolgen zusammengefasst werden.
  • Es gibt keinen Nutzen für 1 = 1
  • Ich empfehle, Ihre "günstigeren" Bedingungen vor die "schwereren" zu schreiben.
  • Ich denke, es ist intuitiver zu bedienen != beim Vergleichen eines Strings, während <> ist besser geeignet, um numerische Werte zu vergleichen.
  • ON-Ausdrücke müssen nicht in Klammern gesetzt werden.
  • $lat in der SELECT-Anweisung sollte für optimale Sicherheitspraktiken als Float umgewandelt werden.
  • Wenn Sie beliebige Aliase für Tabellen verwenden, sollten Sie von a ausgehen und von dort absteigen, anstatt eine fehlerhafte Reihenfolge zu verwenden.
  • ASC ist die Standardsortierrichtung und kann daher entfernt werden.

Ich werde blindlings Ihrer Mathematik vertrauen, und ich kann nicht ganz sicher sein, ob Ihre JOIN-Auswahl korrekt ist, ohne einige Beispieldaten zu haben und die gewünschte Ausgabe zu kennen. Daher lasse ich diese Aspekte in Ruhe.

New 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 ist hier erforderlich, da der Spaltenalias distance noch nicht verfügbar ist, wenn die Logik WHERE implementiert ist.

PHP/Joomla-Äquivalent (ungetestet):

$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");
0
mickmackusa