Можно ли создать 2 предложения where с оператором if?

Мы получили следующие объекты: GeoShape (абстрактный, id, широта и долгота), GeoCircle (просто радиус) и GeoPolygon (просто столбец полигона).

Теперь я хочу запросить все формы с чем-то вроде этого:

if polygon is not null then 
  return ST_CONTAINS(polygon, ...)
else lat,lng in circle then
  return in cirlce

Но то, что я получил это:

if polygon is not null and ST_CONTAINS(polygon, ...) then 
  return true
else lat,lng in circle then
  return in cirlce

Я пытался создать следующий querybuilder, но не могу архивировать то, что я хочу:

        $queryBuilder
        ->join(sprintf('%s.geoShape', $alias), 'geoShape')
        ->where($queryBuilder->expr()->andX(
            $queryBuilder->expr()->isNotNull('polygon'),
            $queryBuilder->expr()->eq('ST_CONTAINS(polygon, Point(:longitude, :latitude))', true)
        ))


        // thats my problem. i don't know how to do the else case


        ->orWhere('
            6371000 * acos(
                cos(
                    radians( :latitude )
                ) * cos(
                    radians( geoShape.center.latitude )
                ) * cos(
                    radians( geoShape.center.longitude ) - radians( :longitude )
                ) + sin(
                    radians( :latitude )
                ) * sin(
                    radians( geoShape.center.latitude )
                )
            ) <= :radius
        ')
        ->setParameters(
            array(
                'latitude' => $location->getLatitude(),
                'longitude' => $location->getLongitude(),
                'radius' => $radius
            )
        );

    return $queryBuilder;

Полигон должен быть важнее круга. Если местоположение не находится в полигоне, то запрос должен остановиться и не проверять наличие круга. Только если полигон не задан.

1 ответ

  1. Я нашел решение. Теперь я просто прошу тип в обоих случаях.

            $qb
            ->join(sprintf('%s.geoShape', $alias), 'shape')
            ->leftJoin(GeoPolygon::class, 'p', Join::WITH, 'shape.id = p.id')
            ->leftJoin(GeoCircle::class, 'c', Join::WITH, 'shape.id = c.id')
            ->where($qb->expr()->andX(
                $qb->expr()->isInstanceOf('shape', GeoPolygon::class),
                $qb->expr()->eq('ST_CONTAINS(p.polygon, Point(:longitude, :latitude))', true)
            ))
            ->orWhere($qb->expr()->andX(
                $qb->expr()->isInstanceOf('shape', GeoCircle::class),
                $qb->expr()->lte('
                6371000 * acos(
                    cos(
                        radians( :latitude )
                    ) * cos(
                        radians( shape.center.latitude )
                    ) * cos(
                        radians( shape.center.longitude ) - radians( :longitude )
                    ) + sin(
                        radians( :latitude )
                    ) * sin(
                        radians( shape.center.latitude )
                    )
                )
            ', $radius)
            ))
            ->setParameters(
                array(
                    'latitude' => $location->getLatitude(),
                    'longitude' => $location->getLongitude()
                )
            );
    
        return $qb;