How to make a Radius calculation in SQL, using Mysql, with two conditions?

Asked

Viewed 343 times

1

Hello,

I already do a radius calculation in SQL, using Mysql and PHP, which takes the location of the device (latitude and longitude) and filters the radius according to the location of the device.

He is like that (excerpt):

(6371 * acos(
        cos( radians('$latitude') )
        * cos( radians( fornecedores.latitude ) )
        * cos( radians( fornecedores.longitude ) - radians('$longitude') )
        + sin( radians('$latitude') )
        * sin( radians( fornecedores.latitude ) ) 
        )
    ) AS distancia
HAVING distancia <= '$raio'

My client now wants suppliers to inform the radius they operate within their latitude and longitude. And when the user sets a radius that can catch this vendor, but this user is outside the range of the same, it is not shown to the user.

I will have to create a new field in the table of suppliers, asking for the range of action of the same (there already has its latitude and longitude). And create a new calculation, similar to this one above, but filtering through this range of action.

I’m not sure how to implement this calculation more with this condition.

Follow my full SQL, in it is the current, without the new field I have to create:

$sql = "SELECT
        (select avg(avaliacao.avaliacao_geral) from avaliacao where avaliacao.cod_fornecedor = fornecedores.cod_fornecedor ) as media_avaliacao,
   fornecedores.cod_fornecedor,
   fornecedores.fantasia,
   fornecedores.CPF,
   fornecedores.identidade,
   fornecedores.email,
   fornecedores.cep,
   fornecedores.logradourro,
   fornecedores.complemento,
   fornecedores.cidade,
   fornecedores.estado,
   fornecedores.responsavel_contato,
   fornecedores.telefone_empresa,
   fornecedores.telefone_responsavel,
   fornecedores.celular,
   fornecedores.bairro,
   fornecedores.numero,
   fornecedores.latitude,
   fornecedores.longitude,
   cadastra_oferta.cod_oferta,
   cadastra_oferta.cod_fornecedor,
   cadastra_oferta.cod_categoria_com,
   cadastra_oferta.titulo_promocao,
   cadastra_oferta.descricao,
   cadastra_oferta.foto,
   cadastra_oferta.valor_sem_desconto,
   cadastra_oferta.valor_com_desconto,
   cadastra_oferta.desconto,
   cadastra_oferta.validade_oferta,
   cadastra_oferta.igredientes,
   cadastra_oferta.qtd_estoque,
   categoria_comida.cod_categoria_com,
   categoria_comida.nome,
   categoria_comida.data_cadastro,
   fornecedor_credito.cod_fornecedor_codigo,
   fornecedor_credito.cod_fornecedor,
   fornecedor_credito.qtd_credito,
   fornecedor_configura_frete.cod_configura_frete,
   fornecedor_configura_frete.cod_fornecedor,
   fornecedor_configura_frete.tem_delivery,
   fornecedor_configura_frete.custo_padrao,
   fornecedor_configura_frete.frete_gratis,
   fornecedor_configura_frete.valor_minimo_frete_gratis,
   fornecedor_configura_frete.tipos_pagamentos,
   fornecedor_configura_frete.prazo_entrega_min,
   fornecedor_configura_frete.prazo_entrega_max,
   fornecedor_configura_frete.agenda_comida,
   fornecedor_configura_frete.dayw_one,
   fornecedor_configura_frete.dayw_two,
   fornecedor_configura_frete.dayw_three,
   fornecedor_configura_frete.dayw_four,
   fornecedor_configura_frete.dayw_five,
   fornecedor_configura_frete.dayw_six,
   fornecedor_configura_frete.dayw_seven,
   fornecedor_configura_frete.hour_ini_one,
   fornecedor_configura_frete.hour_end_one,
   fornecedor_configura_frete.hour_ini_two,
   fornecedor_configura_frete.hour_end_two,
   fornecedor_configura_frete.hour_ini_three,
   fornecedor_configura_frete.hour_end_three,
   fornecedor_configura_frete.hour_ini_four,
   fornecedor_configura_frete.hour_end_four,
   fornecedor_configura_frete.hour_ini_five,
   fornecedor_configura_frete.hour_end_five,
   fornecedor_configura_frete.hour_ini_six,
   fornecedor_configura_frete.hour_end_six,
   fornecedor_configura_frete.hour_ini_seven,
   fornecedor_configura_frete.hour_end_seven,
   fornecedor_visual.cod_fornecedor_visual,
   fornecedor_visual.cod_fornecedor,
   fornecedor_visual.descricao_empresa,
   fornecedor_visual.facebook,
   fornecedor_visual.localizacao_mapa,
   fornecedor_visual.logomarca,
   fornecedor_visual.data_cadastro,
   fornecedor_visual.latitude,
   fornecedor_visual.longitude,
   (6371 * acos(
        cos( radians('$latitude') )
        * cos( radians( fornecedores.latitude ) )
        * cos( radians( fornecedores.longitude ) - radians('$longitude') )
        + sin( radians('$latitude') )
        * sin( radians( fornecedores.latitude ) ) 
        )
    ) AS distancia

FROM   
   fornecedores INNER JOIN cadastra_oferta ON fornecedores.cod_fornecedor = cadastra_oferta.cod_fornecedor
   INNER JOIN categoria_comida ON cadastra_oferta.cod_categoria_com = categoria_comida.cod_categoria_com
   INNER JOIN fornecedor_credito ON fornecedores.cod_fornecedor = fornecedor_credito.cod_fornecedor
   INNER JOIN fornecedor_configura_frete ON fornecedores.cod_fornecedor = fornecedor_configura_frete.cod_fornecedor
   INNER JOIN fornecedor_visual ON fornecedores.cod_fornecedor = fornecedor_visual.cod_fornecedor     
WHERE 
   (fornecedor_credito.qtd_credito >= '1') AND
   (cadastra_oferta.qtd_estoque >= '1')  AND
   (cadastra_oferta.validade_oferta >= NOW()) 
HAVING distancia <= '$raio'
ORDER BY
   cadastra_oferta.titulo_promocao ASC"; 

How can I do that?

1 answer

0


Solved as follows and seems to be working.

  1. I created a new field, in the table supplier_configura_freight called raio_actuacao, I took what was right in the user location filter and changed only the parameters and added another condition:

    (6371 * acos(
        cos( radians('$latitude') )
        * cos( radians( fornecedores.latitude ) )
        * cos( radians( fornecedores.longitude ) - radians('$longitude') )
        + sin( radians('$latitude') )
        * sin( radians( fornecedores.latitude ) ) 
        )
    ) AS distancia,
    (6371 * acos(
        cos( radians(fornecedores.latitude) )
        * cos( radians( '$latitude' ) )
        * cos( radians( '$longitude' ) - radians(fornecedores.longitude) )
        + sin( radians(fornecedores.latitude) )
        * sin( radians( '$latitude' ) ) 
        )
    ) AS distancia_fornecedor
    HAVING distancia <= '$raio' AND distancia_fornecedor <= fornecedor_configura_frete.raio_atuacao
    

Getting the SQL complete this way:

$sql = "SELECT
        (select avg(avaliacao.avaliacao_geral) from avaliacao where avaliacao.cod_fornecedor = fornecedores.cod_fornecedor ) as media_avaliacao,
   fornecedores.cod_fornecedor,
   fornecedores.fantasia,
   fornecedores.CPF,
   fornecedores.identidade,
   fornecedores.email,
   fornecedores.cep,
   fornecedores.logradourro,
   fornecedores.complemento,
   fornecedores.cidade,
   fornecedores.estado,
   fornecedores.responsavel_contato,
   fornecedores.telefone_empresa,
   fornecedores.telefone_responsavel,
   fornecedores.celular,
   fornecedores.bairro,
   fornecedores.numero,
   fornecedores.latitude,
   fornecedores.longitude,
   cadastra_oferta.cod_oferta,
   cadastra_oferta.cod_fornecedor,
   cadastra_oferta.cod_categoria_com,
   cadastra_oferta.titulo_promocao,
   cadastra_oferta.descricao,
   cadastra_oferta.foto,
   cadastra_oferta.valor_sem_desconto,
   cadastra_oferta.valor_com_desconto,
   cadastra_oferta.desconto,
   cadastra_oferta.validade_oferta,
   cadastra_oferta.igredientes,
   cadastra_oferta.qtd_estoque,
   categoria_comida.cod_categoria_com,
   categoria_comida.nome,
   categoria_comida.data_cadastro,
   fornecedor_credito.cod_fornecedor_codigo,
   fornecedor_credito.cod_fornecedor,
   fornecedor_credito.qtd_credito,
   fornecedor_configura_frete.cod_configura_frete,
   fornecedor_configura_frete.cod_fornecedor,
   fornecedor_configura_frete.tem_delivery,
   fornecedor_configura_frete.custo_padrao,
   fornecedor_configura_frete.frete_gratis,
   fornecedor_configura_frete.valor_minimo_frete_gratis,
   fornecedor_configura_frete.tipos_pagamentos,
   fornecedor_configura_frete.prazo_entrega_min,
   fornecedor_configura_frete.prazo_entrega_max,
   fornecedor_configura_frete.agenda_comida,
   fornecedor_configura_frete.raio_atuacao,
   fornecedor_configura_frete.dayw_one,
   fornecedor_configura_frete.dayw_two,
   fornecedor_configura_frete.dayw_three,
   fornecedor_configura_frete.dayw_four,
   fornecedor_configura_frete.dayw_five,
   fornecedor_configura_frete.dayw_six,
   fornecedor_configura_frete.dayw_seven,
   fornecedor_configura_frete.hour_ini_one,
   fornecedor_configura_frete.hour_end_one,
   fornecedor_configura_frete.hour_ini_two,
   fornecedor_configura_frete.hour_end_two,
   fornecedor_configura_frete.hour_ini_three,
   fornecedor_configura_frete.hour_end_three,
   fornecedor_configura_frete.hour_ini_four,
   fornecedor_configura_frete.hour_end_four,
   fornecedor_configura_frete.hour_ini_five,
   fornecedor_configura_frete.hour_end_five,
   fornecedor_configura_frete.hour_ini_six,
   fornecedor_configura_frete.hour_end_six,
   fornecedor_configura_frete.hour_ini_seven,
   fornecedor_configura_frete.hour_end_seven,
   fornecedor_visual.cod_fornecedor_visual,
   fornecedor_visual.cod_fornecedor,
   fornecedor_visual.descricao_empresa,
   fornecedor_visual.facebook,
   fornecedor_visual.localizacao_mapa,
   fornecedor_visual.logomarca,
   fornecedor_visual.data_cadastro,
   fornecedor_visual.latitude,
   fornecedor_visual.longitude,
   (6371 * acos(
        cos( radians('$latitude') )
        * cos( radians( fornecedores.latitude ) )
        * cos( radians( fornecedores.longitude ) - radians('$longitude') )
        + sin( radians('$latitude') )
        * sin( radians( fornecedores.latitude ) ) 
        )
    ) AS distancia,
    (6371 * acos(
        cos( radians(fornecedores.latitude) )
        * cos( radians( '$latitude' ) )
        * cos( radians( '$longitude' ) - radians(fornecedores.longitude) )
        + sin( radians(fornecedores.latitude) )
        * sin( radians( '$latitude' ) ) 
        )
    ) AS distancia_fornecedor
FROM   
   fornecedores INNER JOIN cadastra_oferta ON fornecedores.cod_fornecedor = cadastra_oferta.cod_fornecedor
   INNER JOIN categoria_comida ON cadastra_oferta.cod_categoria_com = categoria_comida.cod_categoria_com
   INNER JOIN fornecedor_credito ON fornecedores.cod_fornecedor = fornecedor_credito.cod_fornecedor
   INNER JOIN fornecedor_configura_frete ON fornecedores.cod_fornecedor = fornecedor_configura_frete.cod_fornecedor
   INNER JOIN fornecedor_visual ON fornecedores.cod_fornecedor = fornecedor_visual.cod_fornecedor     
WHERE 
   (fornecedor_credito.qtd_credito >= '1') AND
   (cadastra_oferta.qtd_estoque >= '1')  AND
   (cadastra_oferta.validade_oferta >= NOW()) 
HAVING distancia <= '$raio' AND distancia_fornecedor <= fornecedor_configura_frete.raio_atuacao
ORDER BY
   cadastra_oferta.titulo_promocao ASC"; 

I did some tests here and it seems to be working perfectly.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.