我有2张桌子。工人桌和工作表。工作人员表接受latitude
,longitude
和work radius
。作业表包含latitude
和longitude
。我需要一个select查询来获取jobs表中的行,但是在worker表的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");
答案 0 :(得分:1)
你需要遍历所有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的绑定有点棘手,因此在进一步说明之前,您必须阅读this part
$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);