tabla - paginacion php mysqli
Compara una consulta con mĂșltiples resultados en PHP (9)
Tengo dos entradas de texto. Me gusta esto:
Por lo tanto, tengo algún tipo de búsqueda dinámica de ajax. Paso los datos de entrada y hago dos mysql select diferentes. Algo como esto:
Tabla de mapa final - SELECCIONA 1
id -------- latitud-----longitud---
1 | 6.2523915 | -75.5737028 |
2 | 6.2640349 | -75.5990783 |
3 | 6.2642411 | -75.5999791 |
4 | 6.2638461 | -75.5982590 |
-------------------------------------
Tabla de mapa final - SELECCIONA 2
id -------- latitud-----longitud---
6 | 6.262669 | -75.596799 |
7 | 6.258019 | -75.598001 |
8 | 6.253668 | -75.599374 |
9 | 6.250724 | -75.602335 |
-------------------------------------
Por lo tanto, quiero comparar cada "campo de latitud y longitud" con todos los campos de "latitud" y "longitud" de SELECT2:
Tengo este Php, tengo que hacer algunas mejoras pero puedo decir que funcionó:
<?php
$buscar = $_POST[''b''];
$buscarcarrera = $_POST[''c''];
$whatIWant = substr($buscar, strpos($buscar, "Calle") + 5);
$whatIWant2 = substr($buscarcarrera, strpos($buscarcarrera, "Carrera") + 5);
$vacio = "Calle50A";
$vacioc = "Carrera50A";
if (preg_match(''/[A-Za-z]/'', $whatIWant))
{
buscar($buscar, "", $buscarcarrera, "");
}
else
{
buscar($buscar, $vacio, $buscarcarrera, $vacioc);
}
function buscar($b, $exclusion, $buscarcarrera, $exclusion2)
{
$con = mysql_connect(''localhost'', ''root'', '''');
mysql_select_db(''map'', $con);
$sql = mysql_query("SELECT * FROM finalmap WHERE calle LIKE ''%" . $b . "%'' AND calle not in (''$exclusion'')", $con);
$contar = mysql_num_rows($sql);
if ($contar == 0)
{
echo "No se han encontrado resultados para ''<b>" . $b . "</b>''.";
}
else
{
while ($row = mysql_fetch_array($sql))
{
$nombre = $row[''calle''];
$id = $row[''id''];
$lat = $row[''latitud''];
$lon = $row[''longitud''];
}
}
$sql2 = mysql_query("SELECT * FROM finalmap WHERE calle LIKE ''%" . $buscarcarrera . "%'' AND calle not in (''$exclusion2'')", $con);
$contar2 = mysql_num_rows($sql2);
if ($contar2 == 0)
{
echo "No se han encontrado resultados para ''<b>" . $b . "</b>''.";
}
else
{
while ($row2 = mysql_fetch_array($sql2))
{
$nombre2 = $row2[''calle''];
$id2 = $row2[''id''];
$lat2 = $row2[''latitud''];
$lon2 = $row2[''longitud''];
}
}
}
function distance($lat1, $lon1, $lat2, $lon2, $unit)
{
$theta = $lon1 - $lon2;
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
$dist = acos($dist);
$dist = rad2deg($dist);
$miles = $dist * 60 * 1.1515;
$unit = strtoupper($unit);
if ($unit == "K")
{
return ($miles * 1.609344);
}
else
if ($unit == "N")
{
return ($miles * 0.8684);
}
else
{
return $miles;
}
}
echo distance(32.9697, -96.80322, 29.46786, -98.53506, "M") . " Miles<br />";
echo distance(32.9697, -96.80322, 29.46786, -98.53506, "K") . " Kilometers<br />";
echo distance(32.9697, -96.80322, 29.46786, -98.53506, "N") . " Nautical Miles<br />";
?>
Entonces: ¿cómo se puede comparar cada uno de los valores usando la función para determinar la proximidad entre las coordenadas (usando la función my distance()
)? Mi problema es que no sé cómo comparar la distancia entre cada punto de la primera consulta con cada punto de la segunda consulta, con todas las combinaciones posibles.
Quiero tener algo como esta función de comparación (lat1, lon1, lat2, lon2); (lat1, lon1, lat3, lon3), (lat1, lon1, lat4, lon4), (lat1, lon1, lat5, lon5), (lat1, lon1, lat6, lon6) y así sucesivamente.
Muchas gracias de antemano por cualquier ayuda prestada
Apoyaría this respuesta, pero agregaría el otro punto importante:
Cuarto: no utilice el cálculo de la distancia y la clasificación con la fórmula de la línea de datos codificada de forma personalizada ni en PHP ni en MySQL. MySQL tiene soporte para funciones espaciales desde hace mucho tiempo. Además, cuando se trata de GIS, es mejor pasar a la extensión PostgreSQL + PostGIS
Quinto: utilice MySQL o cualquier otro índice espacial RDBMS cuando ordene por distancia. Dudo que pueda codificar algo más eficiente con su enfoque de "comparación de cada distancia".
Solución: revise this respuesta y aplique las siguientes consultas a su tabla de base de datos:
ALTER TABLE `finalmap` ENGINE=MYISAM; -- changing your storage engine to MyISAM. It supports spatial indexes in MySQL
ALTER TABLE `finalmap` ADD `pt` POINT NOT NULL; -- adding POINT() spatial datatype for zip cetner. Eventually, you may remove the old lat/lng decimal columns
UPDATE `finalmap` SET `pt` = POINT(latitud,longitud);
ALTER TABLE `finalmap` ADD SPATIAL INDEX(`pt`);
Luego, asumiendo que obtiene una coordenadas en la entrada (digamos (6.25, -75.6)) que necesita comparar con todos los registros en su tabla y encontrar el más cercano, necesita:
SELECT *, ST_Distance_Sphere(`pt`,POINT(''6.25'',''-75.6'')) as `dst`
FROM `fnialmap`
ORDER BY `dst`
LIMIT 1;
Y, finalmente, sexto : por favor, nombre sus columnas y variables en inglés. Puede ser que alguien más admita su código en el futuro y tenga que lidiar con "latitud" y "longitud".
Creo que la combinación de tablas hará su trabajo.
Digamos que la primera tabla es Table1 y la segunda es Table2. Así que la consulta:
Select Table1.id, Table1.latitud, Table1.longitude,
Table2.id, Table2.latitud, Table2.longitude
from
Table1 , Table2
Esto te dará toda la combinación que requieras.
Deberías hacer algo como esto:
function buscar($b, $exclusion, $buscarcarrera, $exclusion2)
{
$nombre1 = array();
$id1= array();
$lat1= array();
$lon1= array();
$nombre2 = array();
$id2= array();
$lat2= array();
$lon2= array();
$con = mysql_connect(''localhost'', ''root'', '''');
mysql_select_db(''map'', $con);
$sql = mysql_query("SELECT * FROM finalmap WHERE calle LIKE ''%" . $b . "%'' AND calle not in (''$exclusion'')", $con);
$contar = mysql_num_rows($sql);
if ($contar == 0)
{
echo "No se han encontrado resultados para ''<b>" . $b . "</b>''.";
} else {
while ($row = mysql_fetch_array($sql))
{
if(array_key_exists(''calle'',$row) && array_key_exists(''id'',$row) && array_key_exists(''latitud'',$row) && array_key_exists(''longitud'',$row)) {
// ignore data with a missing field
$nombre1[] = $row[''calle''];
$id1[] = $row[''id''];
$lat1[] = $row[''latitud''];
$lon1[] = $row[''longitud''];
}
}
}
$sql2 = mysql_query("SELECT * FROM finalmap WHERE calle LIKE ''%" . $buscarcarrera . "%'' AND calle not in (''$exclusion2'')", $con);
$contar2 = mysql_num_rows($sql2);
if ($contar2 == 0)
{
echo "No se han encontrado resultados para ''<b>" . $b . "</b>''.";
} else {
while ($row2 = mysql_fetch_array($sql2))
{
if(array_key_exists(''calle'',$row2) && array_key_exists(''id'',$row2) && array_key_exists(''latitud'',$row2) && array_key_exists(''longitud'',$row2)) {
// ignore data with a missing field
$nombre2[] = $row2[''calle''];
$id2[] = $row2[''id''];
$lat2[] = $row2[''latitud''];
$lon2[] = $row2[''longitud''];
}
}
}
$nbData1 = count($nombre1);
$nbData2 = count($nombre2);
if($nbData1 > 0 && $nbData2 > 0) {
// there are data in both 1st and 2nd query
$distances = array();
// loop on all data from 1st query
for($i1 = 0; $i1 < $nbData1; $i1++) {
// loop on all data from 2nd query
for($i2 = $i1; $i2 < $nbData2; $i2++) {
// storing result of the distance
$distances[] = array(''i1'' => $i1,
''i2'' => $i2,
''dist'' => array(''M'' => distance($lat1[$i1], $lon1[$i1], $lat2[$i2], $lon2[$i2], ''M''),
''K'' => distance($lat1[$i1], $lon1[$i1], $lat2[$i2], $lon2[$i2], ''K''),
''N'' => distance($lat1[$i1], $lon1[$i1], $lat2[$i2], $lon2[$i2], ''N'')
)
)
}
}
}
foreach($distances as $distance) {
// use each result
$i1 = $distance[''i1''];
$lat1 = $distance[''lat1''];
$lon1 = $distance[''lon1''];
$i2 = $distance[''i1''];
$lat2 = $distance[''lat2''];
$lon2 = $distance[''lon2''];
$dist = $distance[''dist''];
$distM = $dist[''M''];
$distK = $dist[''K''];
$distN = $dist[''N''];
echo "Have fun with theses data !/n";
}
}
Así, almacenando el contenido de tus filas.
Luego analiza todos tus datos, para calcular todas las distancias posibles.
Luego usa el resultado como desees.
Esto es mucho mejor para procesar el cálculo de la distancia en la segunda consulta, y esto es más rápido, por lo que la función distance () no es necesaria. También parece que tu fórmula no es correcta.
$buscar = $_POST[''b''];
$buscarcarrera = $_POST[''c''];
$whatIWant = substr($buscar, strpos($buscar, "Calle") + 5);
$whatIWant2 = substr($buscarcarrera, strpos($buscarcarrera, "Carrera") + 5);
$vacio = "Calle50A";
$vacioc = "Carrera50A";
if (preg_match(''/[A-Za-z]/'', $whatIWant))
{
buscar($buscar, "", $buscarcarrera, "");
}
else
{
buscar($buscar, $vacio, $buscarcarrera, $vacioc);
}
function buscar($b, $exclusion, $buscarcarrera, $exclusion2)
{
$con = mysql_connect(''localhost'', ''root'', '''');
mysql_select_db(''map'', $con);
$sql = mysql_query("SELECT * FROM finalmap WHERE calle LIKE ''%" . $b . "%'' AND calle not in (''$exclusion'')", $con);
$contar = mysql_num_rows($sql);
if ($contar == 0)
{
echo "No se han encontrado resultados para ''<b>" . $b . "</b>''.";
}
else
{
while ($row = mysql_fetch_array($sql))
{
$nombre = $row[''calle''];
$id = $row[''id''];
$lat = $row[''latitud''];
$lon = $row[''longitud''];
$dLat = ''((latitud-''.$lat.'')*PI()/180)'';
$dLong = ''((longitud-''.$lon.'')*PI()/180)'';
$a = ''(sin(''.$dLat.''/2) * sin(''.$dLat.''/2) + cos(''.$lat.''*pi()/180) * cos(map_coords_1*pi()/180) * sin(''.$dLong.''/2) * sin(''.$dLong.''/2))'';
$sub_sql = ''2*atan2(sqrt(''.$a.''), sqrt(1-''.$a.''))'';
$results = mysql_query(
"SELECT DISTINCT
id, calle, " . $sub_sql . " AS distance FROM finalmap
WHERE
calle LIKE ''%" . $buscarcarrera . "%'' AND calle not in (''$exclusion2'')
ORDER BY
distance
", $con);
if ($results == 0)
{
echo "No se han encontrado resultados para ''<b>" . $buscarcarrera . "</b>''.";
}
else
{
while ($row2 = mysql_fetch_array($results)) {
echo "Calle: " . $row2[''calle''] . " Miles - " . $row2[''distance'']*3956;
echo "Calle: " . $row2[''calle''] . " Kilometers - " . $row2[''distance'']*6367;
echo "Calle: " . $row2[''calle''] . " Nautical Miles - " . $row2[''distance'']*3435;
}
}
}
}
}
Le estoy dando un primer intento.
$output_array = array();
$i = 0;
while ($row = mysql_fetch_array($sql))
{
$j = 0;
while ($row2 = mysql_fetch_array($sql2))
{
$out_array[$i][$j][0] = $row2[''latitud''] - $row[''latitud'']
$out_array[$i][$j][1] = $row2[''longitud''] - $row[''longitud'']
++$j;
}
++$i;
}
print "<pre>";
print_r($out_array);
print "</pre>";
Vista previa (con números aleatorios):
Array
(
[0] => Array
(
[0] => Array
(
[0] => 6
[1] => 9
)
[1] => Array
(
[0] => 6
[1] => 9
)
[2] => Array
(
[0] => 6
[1] => 9
)
............
............
............
Array [0] [0] [0] == diferencia entre la latitud del primer resultado (tabla 1) y la latitud del primer resultado (tabla 2)
Array [0] [1] [0] == diferencia de latitud (1ª tabla de resolución 1) Y (2ª tabla de resolución 2)
Mismo caso para la longitud.
Puedes tomar el producto cartesiano de ambas tablas para que puedas encontrar todas las combinaciones posibles.
De lo contrario, toma dos bucles como
for(int i=0;i < n; i++)
for(int j=0; j< m; j++)
someProcess(a[i][0], a[i][1], b[j][0], b[j][1]);
Y esto te dará todas las combinaciones posibles.
Su función debe tener lógica para la geocodificación / geocodificación inversa para calcular la distancia.
¡¡Espero que esto ayude!!
Sin embargo, puede generar fácilmente el conjunto de resultados necesario en SQL sin tener que escribir un montón de código PHP.
También haría las cosas mucho más fáciles si realmente mostraras cómo quieres que se vean tus resultados como una tabla. Estoy confundido en cuanto a lo que realmente estás tratando de hacer. Mi suposición es que desea hacer coincidir las dos consultas cuando las latitudes coinciden exactamente O las longitudes coinciden exactamente.
Actualización: encontré el SQL enterrado en su código PHP. Algo como esto debería funcionar:
"SELECT t1.latitud AS lat1, t1.longitud AS lon1,
t2.latitud AS lat2, t2.longitud AS lon2
FROM finalmap AS t1
INNER JOIN finalmap AS t2 ON t1.latitud=t2.latitud OR t1.longitud=t2.longitud
WHERE t1.calle LIKE ''%" . $b . "%'' AND t1.calle not in (''$exclusion'')
AND t2.calle LIKE ''%" . $buscarcarrera . "%'' AND t2.calle NOT IN (''exclusion2'');"
Si desea todos los resultados de SELECT 1, incluso si no hay coincidencias en SELECT 2, cambie la INNER JOIN
a LEFT JOIN
.
También noté que está comprobando si los campos tienen valores después de que se devuelva la consulta. Puede realizar esas comprobaciones en la cláusula WHERE
de la consulta SQL de manera que no obtenga los resultados que realmente no desea. Solo depende de cómo se vea un "sin valor" (¿NULO? ¿Cadena vacía? Etc.) en cuanto a cómo lo verificará.
Tu lógica está completamente equivocada y estás complicando mucho lo que estás buscando. Es mucho más simple de lo que piensas.
Primero: para acelerar drásticamente su script y sus consultas, así como para protegerlo de cualquier ataque, utilice declaraciones preparadas para PDO y protocolos de seguridad. Mysql ninguna de las declaraciones preparadas están en desuso por más de una década !!!
Mi experiencia (25 años de codificación) me muestra que nunca debo confiar en lo que viene en su servidor, por lo que soy un poco fóbico con respecto a la seguridad ... Este tutorial explica los primeros pasos básicos que debe hacer y le explica este guión. debe ser (copiar más allá de todos los códigos como son).
Tenga en cuenta que el uso de una dirección IP local en lugar de Localhost acelerará las conexiones de mysql de 2 a 5, según la plataforma de desarrollo (lámpara, lámpara, etc.)
establecer parámetros de ejecución
ini_set(''memory_limit'', ''64M''); // memory limit used by script
set_time_limit(0); // no time limit
Establezca su conexión mysql asegurada
try {
$con = new PDO(''mysql:host=127.0.0.1;dbname=map;charset=UTF8'',''root'',''password'');
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo ''Connection failed: '' . $e->getMessage();
}
Establezca un protocolo de seguridad de segundo nivel para verificar si realmente es una llamada ajax
$isAjax = isset($_SERVER[''HTTP_X_REQUESTED_WITH'']) AND
strtolower($_SERVER[''HTTP_X_REQUESTED_WITH'']) === ''xmlhttprequest'';
if (!$isAjax) {
$user_error = ''Access denied - not an AJAX request from allowed computer...'';
trigger_error($user_error, E_USER_ERROR);
exit;
}
Segundo: Use la función de distancia DENTRO de su consulta de mysql para ordenar adecuadamente los resultados que está buscando. Tenga en cuenta que la distancia mysql utilizada aquí es diferente de la que está utilizando actualmente (más rápida y precisa). Le dará la distancia entre los puntos de referencia de la tabla 1 y todos los demás de la tabla 2 en km, ordenados por distancia (lo más cerca posible de la primera fila).
Suponemos que obtienes los resultados de tu ajax de esta manera:
if($isAjax){
$param4 = ''%'' . $_POST[''b'']. ''%''; // MYSQL LIKE bind param buscar
$param5 = ''('' . $_POST[''c''] . '')''; //MYSQL NOT IN bind param buscarcarrera
}
Suponemos que obtiene sus resultados de la primera consulta como esta (simplificada):
$sql1_array = array(
array(''id'' => 1, ''Lati'' => 6.2523915, ''Longi'' => -75.5737028),
array(''id'' => 2, ''Lati'' => 6.2640349, ''Longi'' => -75.5990783)
);
(nota: siempre use "lati" y "longi" para evitar la colisión con la función PHP como "long")
Su declaración preparada:
$sql2 = "SELECT *, ( 6371 * acos( cos(radians(?))
* cos(radians(Latitude)) * cos(radians(Longitude) - radians(?)) +
sin( radians(?) ) * sin(radians(Latitude)))) AS distance
FROM finalmap WHERE calle LIKE ? AND calle NOT IN ?
ORDER BY distance LIMIT 10";
$stmt = $con->prepare($sql2);
Tercero : ejecute un bucle con cada resultado de la consulta1 para obtener las distancias en comparación con la tabla 2. En el bucle, debe vincular sus parámetros a su estado preparado. Esto acelerará drásticamente sus consultas, ya que la conexión con la base de datos es persistente y la consulta se prepara con PDO (compilada y en memoria).
foreach ($sql1_array as $key => $value) {
$stmt->bindParam(1, $value[''Lati''], PDO::PARAM_INT);
$stmt->bindParam(2, $value[''Longi''], PDO::PARAM_INT);
$stmt->bindParam(3, $value[''Lati''], PDO::PARAM_INT);
$stmt->bindParam(4, $param4, PDO::PARAM_STR);
$stmt->bindParam(5, $param5, PDO::PARAM_STR);
$stmt->execute();
$count = $stmt->rowCount();
if ($count >= 1) {
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
}
/* $result ordered by distance */
|**************************************|
|field 0 | field 1 | field 2 | distance|
|**************************************|
| 1 | a1 | a2 | 0.00123 | 1 meters
| 2 | b1 | b2 | 0.01202 | 12 meters
| 3 | c1 | c2 | 0.23453 | 234 meters
| 4 | d1 | d2 | 1.58741 | 1km and 587 meters
|**************************************|
¡Creo que estás listo! Disfrutar.
Creo que INNER JOIN funcionará. Estoy confundido de que proporcionará la tabla 1 largo y el valor lat o no.
Así que estoy escribiendo ambas opciones.
Digamos que la primera tabla es table1 y la segunda es table2
- Cuando proporcionará el valor lat y long de la tabla 1
SELECT * FROM table1 AS t1 INNER JOIN table2 AS t2 ON t1.latitude=t2.latitud OR t2.longitude=t1.longitude WHERE t1.latitude=''#enter the value#'' AND t1.longitude=''#enter the value#''
- Proporcionará el resultado del filtro del valor igual en ambas tablas.
SELECT * FROM table1 AS t1 INNER JOIN table2 AS t2 ON t1.latitude=t2.latitud OR t2.longitude=t1.longitude
Déjame saber si necesita algo más.
Agradeciendote.