sql — сравнение одного запроса с несколькими результатами в переполнении стека

У меня есть два ввода текста. Как это:

введите описание изображения здесь

Итак, у меня есть какой-то динамический поиск ajax. Я передаю входные данные и выбираю два разных mysql. Что-то вроде этого:

Финальная карта таблицы — ВЫБЕРИТЕ 1

id -------- latitud-----longitud---

1        |  6.2523915 | -75.5737028 |
2        |  6.2640349 | -75.5990783 |
3        |  6.2642411 | -75.5999791 |
4        |  6.2638461 | -75.5982590 |
-------------------------------------

Финальная карта таблицы — ВЫБОР 2

id -------- latitud-----longitud---

6        |  6.262669 | -75.596799 |
7        |  6.258019 | -75.598001 |
8        |  6.253668 | -75.599374 |
9        |  6.250724 | -75.602335 |
-------------------------------------

Итак, я хочу сравнить каждое «широтное и продольное поле» со всеми «широтным» и «продольным» полями SELECT2:

введите описание изображения здесь

У меня есть этот Php, я должен сделать некоторые улучшения, но могу сказать, что он работал:

<?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 />";
?>

Затем: как можно сравнить каждое из значений, используя функцию для определения близости между координатами (используя мой distance() функция) ?. Моя проблема в том, что я не знаю, как сравнить расстояние между каждой точкой 1-го запроса с каждой точкой 2-го запроса, с каждой возможной комбинацией.

Я хочу иметь что-то вроде этой функции сравнения (lat1, lon1, lat2, lon2);
(lat1, lon1, lat3, lon3), (lat1, lon1, lat4, lon4), (lat1, lon1, lat5, lon5), (lat1, lon1, lat6, lon6) и так далее.

Большое спасибо заранее за любую помощь

16

Решение

Ваша логика совершенно неверна, и вы слишком усложняете то, что ищете. Это намного проще, чем вы думаете.

Первый: Чтобы значительно ускорить выполнение сценария и запросов, а также защитить его от любых атак, используйте подготовленные операторы PDO и протоколы безопасности. Mysql ни один из подготовленных заявлений не рекомендуется более десяти лет !!!

Мой опыт (25 лет программирования) показывает, что я никогда не доверяю тому, что приходит на ваш сервер, поэтому я немного страдаю безопасностью ….
В этом руководстве объясняются первые основные шаги, которые необходимо выполнить, и объясняется, как должен быть выполнен этот сценарий (скопируйте все коды, как они есть).

Обратите внимание, что использование локального IP-адреса вместо Localhost ускорит MySQL-соединения на 2–5 в зависимости от платформы разработчика (лампа, wamp и т. Д.)

установить параметры выполнения

ini_set('memory_limit', '64M'); // memory limit used by script
set_time_limit(0);              // no time limit

Установите безопасное соединение MySQL

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();
}

Установите протокол безопасности второго уровня, чтобы проверить, действительно ли это вызов 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;
}

Во-вторых: Используйте функцию расстояния ВНУТРИ Ваш запрос MySQL, чтобы правильно отсортировать результаты, которые вы ищете. Обратите внимание, что расстояние mysql, используемое здесь, отличается от того, которое вы используете в настоящее время (быстрее и точнее).
Это даст вам расстояние между контрольными точками из таблицы 1 и всеми другими из таблицы 2 в км, упорядоченными по расстоянию (ближайший как первый ряд).

Мы предполагаем, что вы получаете свои результаты от вашего AJAX следующим образом:

if($isAjax){
$param4 = '%' . $_POST['b']. '%';  // MYSQL LIKE bind param buscar
$param5 = '(' . $_POST['c'] . ')'; //MYSQL NOT IN bind param  buscarcarrera
}

Мы предполагаем, что вы получите результаты первого запроса, как это (упрощенно):

$sql1_array = array(
array('id' => 1, 'Lati' => 6.2523915, 'Longi' => -75.5737028),
array('id' => 2, 'Lati' => 6.2640349, 'Longi' => -75.5990783)
);

(примечание: всегда используйте «lati» и «longi», чтобы избежать столкновения с функцией PHP, такой как «long»)

Ваше подготовленное заявление:

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

В третьих: Выполните цикл с каждым результатом query1, чтобы получить расстояния, сравниваемые с таблицей 2. В цикле вы привязываете свои параметры к подготовленному stmt. Это значительно ускорит ваши запросы, так как соединение с базой данных является постоянным, а запрос подготовлен с помощью PDO (скомпилировано и в памяти).

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

Я думаю, что вы все готово! Наслаждаться.

7

Другие решения

Вы должны сделать что-то вроде этого:

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

Итак, хранение содержимого ваших строк.
Затем проанализируйте все ваши данные, чтобы рассчитать все возможные расстояния.
Затем используйте результат, как вы хотите.

2

Это намного лучше для обработки вычисления расстояния во втором запросе, и это быстрее, поэтому функция distance () не нужна. Также кажется, что ваша формула не верна.

$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;
}
}
}
}
}
1

Я делаю это с первой попытки.

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

Предварительный просмотр (со случайными числами):

 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] == разница между 1-м результатом широтно (таблица 1) А ТАКЖЕ 1-й результат по широте (таблица 2)

Array [0] [1] [0] == разница широта (1-ая таблица рез1) А ТАКЖЕ (2-е место в таблице 2)

То же самое для продольного.

0

Я думаю перекрестное соединение стола будет делать вашу работу.

Допустим, первая таблица — это Таблица1, а вторая — Таблица2.
Итак, запрос:

Select Table1.id, Table1.latitud, Table1.longitude,
Table2.id, Table2.latitud, Table2.longitude
from
Table1 , Table2

Это даст вам все комбинации, которые вам необходимы.

0

Я думаю, что INNER JOIN будет работать. Я просто сбит с толку, что вы предоставите table-1 long и значение lat или нет.
Поэтому я пишу оба варианта.
Допустим, первая таблица — это table1, а вторая — table2.

  1. Когда вы предоставите lat и long значение таблицы 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#'
  2. Это обеспечит результат фильтра равного значения в обеих таблицах
    SELECT * FROM table1 AS t1 INNER JOIN table2 AS t2 ON t1.latitude=t2.latitud OR t2.longitude=t1.longitude 

Дайте мне знать, если нужно что-нибудь еще.
Благодарю вас.

0

Вы можете легко сгенерировать необходимый набор результатов в SQL без необходимости писать кучу кода PHP.

Также было бы намного проще, если бы вы на самом деле показали, как вы хотите, чтобы ваши результаты выглядели в виде таблицы. Я не понимаю, что вы на самом деле пытаетесь сделать. Я предполагаю, что вы хотите сопоставить два запроса, когда либо широта совпадает точно ИЛИ ЖЕ долготы точно совпадают.

Обновление: я нашел SQL похоронен в вашем коде PHP. Примерно так должно работать:

"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');"

Если вы хотите получить все результаты из SELECT 1, даже если в SELECT 2 нет совпадений, измените INNER JOIN к LEFT JOIN,

Я также заметил, что вы проверяете, имеют ли поля значения после возврата запроса. Вы можете сделать эти проверки в WHERE предложение SQL-запроса таким образом, что вы не получите никаких результатов, которые вы на самом деле не хотите. Это зависит только от того, как выглядит «без значения» (NULL? Пустая строка? И т. Д.), От того, как вы это проверите.

0

Вы можете взять декартово произведение обеих таблиц, чтобы найти все возможные комбинации.

В противном случае возьмите две петли, как

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

И это даст вам все возможные комбинации.

Ваша функция должна иметь логику для геокодирования / обратного геокодирования для вычисления расстояния.


Надеюсь, это поможет!!

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector