У меня 2 таблицы. таблица рабочих мест и рабочих мест. Рабочий стол принимает latitude
, longitude
и work radius
. Таблица рабочих мест имеет latitude
и longitude
. Мне нужен запрос выбора, который получает строки из таблицы заданий, но в пределах work radius
работы рабочей таблицы.
Ниже приведена структура таблиц и то, что у меня есть до сих пор, это выбор из таблицы на основе широты и долготы.
Спасибо за любую помощь.
Рабочий стол:
CREATE TABLE "worker" (
"id" varchar(25) NOT NULL,
"latitude" varchar(25) NOT NULL,
"longitude" varchar(25) NOT NULL,
"work_radius" int(25) NOT NULL,
"address" varchar(255) NOT NULL,
PRIMARY KEY ("id")
);
Таблица рабочих мест:
CREATE TABLE "jobs" (
"id" varchar(25) NOT NULL,
"latitude" varchar(25) NOT NULL,
"longitude" varchar(25) NOT NULL,
"address" varchar(255) NOT NULL,
PRIMARY KEY ("id")
);
Выберите запрос:
$jobs_load = $dbh->prepare("
SELECT
'*',
(
6371 *
acos(
cos( radians( :lat_id ) ) *
cos( radians( 'lat_id' ) ) *
cos(
radians( 'long_id' ) - radians( :long_id )
) +
sin(radians(:lat_id) *
sin(radians('lat_id'))
)
) 'work_radius'
FROM
'jobs'
HAVING
'work_radius' < :work_radius
ORDER BY
'work_radius'
LIMIT
25");
Вам нужно зациклиться на всем worker
тогда для каждого работника найдите работу в пределах своего диапазона, попробуйте это
$conn = $conn = new PDO("mysql:host=localhost;dbname=test", 'root', '');
$result = $conn->query("SELECT * FROM worker");
$allWorkers = [];
foreach($result as $row)
{
$allWorkers[] = array(
'id'=> $row["id"],
'latitude'=>$row["latitude"],
'longitude'=>$row["longitude"],
'work_radius'=> $row["work_radius"]
);
}
$distance_query = 'SELECT
*, (
6371 * acos (
cos ( radians(:latitude) )
* cos( radians( latitude) )
* cos( radians( longitude ) - radians(:longitude) )
+ sin ( radians(:latitude) )
* sin( radians( latitude) )
)
) AS distance
FROM jobs
having distance < :work_radius
ORDER BY distance
LIMIT 0 , 20;';
$workers_jobs = array();
$stmt = $conn->prepare($distance_query);
foreach( $allWorkers as $worker)
{
$stmt->bindParam(':latitude', $worker['latitude']);
$stmt->bindParam(':longitude', $worker['longitude']);
$stmt->bindParam(':work_radius', $worker['work_radius']);
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$workers_jobs[$worker['id']]['id'] = $row['id'];
$workers_jobs[$worker['id']]['latitude'] = $row['latitude'];
$workers_jobs[$worker['id']]['longitude'] = $row['longitude'];
}
}
//$ workers_jobs удерживает одну строку на одного работника и его работу
ОБНОВИТЬ
Предположим, что у вас есть дополнительный столбец, который говорит " Shift " (varchar 50) в таблице рабочих мест
+----+-----------+-----------+---------+
| id | latitude | longitude | Shift |
+----+-----------+-----------+---------+
| 1 | 51.919438 | 19.145136 | morning |
| 2 | 49.852276 | 15.015519 | evening |
| 3 | 49.208705 | 11.946989 | night |
+----+-----------+-----------+---------+
как включить это в ваш $distance_query
? Ну, привязка для IN немного сложна, поэтому, прежде чем двигаться дальше, вы должны прочитать эту часть
$conn = $conn = new PDO("mysql:host=localhost;dbname=test", 'root', '');
$result = $conn->query("SELECT * FROM worker");
$allWorkers = [];
foreach($result as $row)
{
$allWorkers[] = array(
'id'=> $row["id"],
'latitude'=>$row["latitude"],
'longitude'=>$row["longitude"],
'work_radius'=> $row["work_radius"]
);
}
//** bind IN - placeholders**//
$shifts = ['morning','night'];
$in = '';
foreach ($shifts as $i => $item)
{
$key = ':shift'.$i;
$in .= "$key,";
}
$in = rtrim($in, ',');
//** bind IN - placeholders end **//
$distance_query = 'SELECT
*, (
6371 * acos (
cos ( radians(:latitude) )
* cos( radians( latitude) )
* cos( radians( longitude ) - radians(:longitude) )
+ sin ( radians(:latitude) )
* sin( radians( latitude) )
)
) AS distance
FROM jobs
where shift IN (' . $in . ')
having distance < :work_radius
ORDER BY distance
LIMIT 0 , 20;';
$workers_jobs = array();
$stmt = $conn->prepare($distance_query);
foreach( $allWorkers as $worker)
{
$stmt->bindParam(':latitude', $worker['latitude']);
$stmt->bindParam(':longitude', $worker['longitude']);
$stmt->bindParam(':work_radius', $worker['work_radius']);
//** bind IN - values**//
$shifts = ['morning','night'];
$in = '';
foreach ($shifts as $i => $item)
{
$key = ':shift'.$i;
$stmt->bindParam($key, $item);
}
//** bind IN - values ends**//
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$workers_jobs[$worker['id']]['id'] = $row['id'];
$workers_jobs[$worker['id']]['latitude'] = $row['latitude'];
$workers_jobs[$worker['id']]['longitude'] = $row['longitude'];
}
}
echo '<pre>'; print_r($workers_jobs);
$result = $conn->query("SELECT * FROM worker where id=$worker_id");