Mysql 当在PhpMyAdmin中运行时,在何处给我不同的结果
当我在phpMyAdmin中运行以下查询时Mysql 当在PhpMyAdmin中运行时,在何处给我不同的结果,mysql,laravel,Mysql,Laravel,当我在phpMyAdmin中运行以下查询时 SELECT locations.name, locations.id, locations.lon, locations.lat, locations_categories.category_id as catId, locations_categories.location_id as locId, haversine(40,9
SELECT
locations.name,
locations.id,
locations.lon,
locations.lat,
locations_categories.category_id as catId,
locations_categories.location_id as locId,
haversine(40,90,locations.lon,locations.lat) as distance
FROM locations_categories, locations
WHERE locations.id = locations_categories.location_id
AND locations_categories.category_id IN ("9","1","7")
ORDER BY `distance` ASC
它给出了以下正确的结果
但是,当我在Laravel应用程序中运行以下命令时,它只返回catId为9的位置
// dump($request->categories);
$categories = implode('","',$request->categories);
//dd($categories);
$statement = <<<'ENDSTATEMENT'
SELECT
locations.name,
locations.id,
locations.lon,
locations.lat,
locations_categories.category_id as catId,
locations_categories.location_id as locId,
haversine(?,?,locations.lon,locations.lat) as distance
FROM locations_categories, locations
WHERE locations.id = locations_categories.location_id
AND locations_categories.category_id IN (?)
ORDER BY `distance` ASC
ENDSTATEMENT;
$locations = DB::select($statement, array($request->lon, $request->lat, $categories));
下面是截图
我的问题是,为什么这可以工作并返回PhpMyAdmin中所需的所有值,但在应用程序中运行时却不能?在这里使用Laravel代码,而不是单个原始查询。这允许您利用
WHERE
函数,该函数可以将PHP值数组正确绑定到WHERE
表达式
$locations = DB::table('locations_categories as lc')
->join('locations', 'locations.id', '=', 'lc.location_id')
->whereIn('lc.category_id', $request->categories)
->selectRaw('locations.name, locations.id, locations.lon, locations.lat,'
. 'lc.category_id as catId,'
. 'lc.location_id as locId,'
. 'haversine(?, ?, locations.lon,locations.lat) as distance',
[$request->lon, $request->lat])
->get();
您的问题的答案与如何实现绑定变量以及类型强制有关 绑定的
?
将替换为单个值。这不是简单的SQL语句搜索和替换。因此,在(?)中的位置\u categories.category\u id中,?
的值实际上是整个值9”、“1”、“7
。但是,为什么它仍然返回locations\u categories.category\u id=9的结果呢
因为类型强制。我假设locations\u categories.category\u id
是一个数字列,而不是架构中的字符类型列。因此,当执行SQL时,右侧的字符串值,9”、“1”、“7
被强制转换为一个数字表示,它恰好是9
。您可以在这里更明确地看到:
mysql> select cast('9","1","7' as signed);
+-----------------------------+
| cast('9","1","7' as signed) |
+-----------------------------+
| 9 |
+-----------------------------+
1 row in set, 1 warning (0.05 sec)
mysql> show warnings;
+---------+------+------------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------------+
| Warning | 1292 | Truncated incorrect INTEGER value: '9","1","7' |
+---------+------+------------------------------------------------+
1 row in set (0.04 sec)
原始查询必须如下所示,并传递一个参数数组以绑定到select:
SELECT
locations.name,
locations.id,
locations.lon,
locations.lat,
locations_categories.category_id as catId,
locations_categories.location_id as locId,
haversine(:req_lon, :req_lat, locations.lon, locations.lat) as distance
FROM locations_categories, locations
WHERE
locations.id = locations_categories.location_id AND
locations_categories.category_id IN (:cat0, :cat1, :cat2)
ORDER BY `distance` ASC
将该代码与参数一起使用以绑定:
$categories = ["9","1","7"]; // example
$bind = [];
foreach($categories as $k => $cat) {
$bind['cat'.$k] = $cat;
}
$listCat = implode(', ', array_keys($bind));
// add others filters
$bind['req_lon'] = $request->lon;
$bind['req_lat'] = $request->lat;
$sql =
" SELECT
locations.name,
locations.id,
locations.lon,
locations.lat,
locations_categories.category_id as catId,
locations_categories.location_id as locId,
haversine(:req_lon, :req_lat, locations.lon, locations.lat) as distance
FROM locations_categories, locations
WHERE
locations.id = locations_categories.location_id AND
locations_categories.category_id IN ({$listCat})
ORDER BY `distance` ASC";
$locations = DB::select($sql, $bind);
很简单:“9”、“1”、“7”
是三个不同的值,而“9”、“1”、“7”
被视为单个字符串,并在其周围附加引号。@LukaszSzozda我也注意到了这一点,我认为这是问题所在,但当它仍然搜索9时,我感到困惑。你知道如何解决这个问题吗?Laravel有一个函数,其中函数接受一个PHP值数组。但是,似乎没有任何方法可以按照您想要的方式直接绑定PHP数组。有一些选择。非常感谢!我将用正确的工作代码对您的答案进行一些编辑,然后我将接受您的答案!
$categories = ["9","1","7"]; // example
$bind = [];
foreach($categories as $k => $cat) {
$bind['cat'.$k] = $cat;
}
$listCat = implode(', ', array_keys($bind));
// add others filters
$bind['req_lon'] = $request->lon;
$bind['req_lat'] = $request->lat;
$sql =
" SELECT
locations.name,
locations.id,
locations.lon,
locations.lat,
locations_categories.category_id as catId,
locations_categories.location_id as locId,
haversine(:req_lon, :req_lat, locations.lon, locations.lat) as distance
FROM locations_categories, locations
WHERE
locations.id = locations_categories.location_id AND
locations_categories.category_id IN ({$listCat})
ORDER BY `distance` ASC";
$locations = DB::select($sql, $bind);