【发布时间】:2016-07-23 19:41:33
【问题描述】:
我尝试解决了一段时间,但没有找到解决方案。
我从一个充满移动设备的表格中读取并列出它们,并让用户可以根据移动设备名称和用户名搜索列表。
这是我的代码:
SELECT
*
FROM
tbl_mobdev
LEFT JOIN
tbl_mobdev_type ON mobdev_type_id = mobdev_type
LEFT JOIN
tbl_marke ON marke_id = mobdev_type_marke
LEFT JOIN
tbl_user ON tbl_user.id = mobdev_user
WHERE
CONCAT(tbl_marke.marke_name,' ',tbl_mobdev_type.mobdev_type_bezeichnung) LIKE '%".$_POST['marke_name']."%'
AND
CONCAT(tbl_user.name,' ',tbl_user.vorname) LIKE '%".$_POST['user']."%'
AND
mobdev_aktiv = '1'
ORDER BY
".$_GET['sort']." ".$_GET['sort2']."
只要 tbl_mobdev.mobdev_user 包含用户 ID,一切都按预期工作,而不包含用户 ID 的表行将被忽略。
有什么解决办法吗?
编辑:将“过滤器”放在 tbl_user 的 LEFT JOIN 中的解决方案不起作用。将显示每行中类似以下结果的 SQL。 如果 LIKE 包含仅不匹配结果的内容,则不会连接该行。
SELECT mobdev_id, mobdev_type_bezeichnung, marke_name, tbl_user.name AS user_name, tbl_user.vorname AS user_vorname
FROM tbl_mobdev
LEFT JOIN tbl_mobdev_type ON mobdev_type_id = mobdev_type
LEFT JOIN tbl_marke ON marke_id = mobdev_type_marke
LEFT JOIN tbl_user ON tbl_user.id = mobdev_user
AND CONCAT( tbl_user.name, ' ', tbl_user.vorname ) LIKE '%%'
WHERE CONCAT( tbl_marke.marke_name, ' ', tbl_mobdev_type.mobdev_type_bezeichnung ) LIKE '%%'
AND mobdev_aktiv = '1'
ORDER BY marke_name ASC
LIMIT 0 , 30
Edit2:将 SQL 设置为以下并没有改变行为。
SELECT mobdev_id, mobdev_type_bezeichnung, marke_name, tbl_user.name AS user_name, tbl_user.vorname AS user_vorname
FROM tbl_mobdev
LEFT JOIN tbl_mobdev_type ON mobdev_type_id = mobdev_type
LEFT JOIN tbl_marke ON marke_id = mobdev_type_marke
LEFT JOIN tbl_user ON tbl_user.id = mobdev_user
AND CONCAT( tbl_user.name, ' ', tbl_user.vorname ) LIKE '%G%'
WHERE CONCAT( tbl_marke.marke_name, ' ', COALESCE( tbl_mobdev_type.mobdev_type_bezeichnung, '' ) ) LIKE '%%'
AND mobdev_aktiv = '1'
ORDER BY marke_name ASC
LIMIT 0 , 30
不匹配 $_POST['user'] 的行仍然不会被过滤掉。
我上传了一张名称模糊的行为示例图片,左图是没有任何过滤器的 Select,右图是具有实际用户名的 Select(模糊,但它的名称与 mobdev_id '3 中的完全相同'。
http://fs5.directupload.net/images/160404/tmdbyzws.png
如您所见,其他五行仍然存在,只是没有连接。我希望它们完全消失,因为它们与过滤器不匹配。
Edit3:好吧,我现在做到了……遗憾的是,使用 PHP 的方式非常肮脏。我只是把代码留在这里,如果有人对此提出更好的解决方案,请告诉我。
$query = "
SELECT
mobdev_id,
mobdev_type_bezeichnung,
marke_name,
tbl_user.name AS user_name,
tbl_user.vorname AS user_vorname
FROM
tbl_mobdev
LEFT JOIN
tbl_mobdev_type ON mobdev_type_id = mobdev_type
LEFT JOIN
tbl_marke ON marke_id = mobdev_type_marke
LEFT JOIN
tbl_user ON tbl_user.id = mobdev_user
WHERE
CONCAT(tbl_marke.marke_name,' ',tbl_mobdev_type.mobdev_type_bezeichnung) LIKE '%".$_POST['marke_name']."%'
";
if($_POST['user'])
{
$query .= "
AND
CONCAT(tbl_user.name,' ',tbl_user.vorname) LIKE '%".$_POST['user']."%'
";
}
$query .= "
AND
mobdev_aktiv = '1'
ORDER BY
".$_GET['sort']." ".$_GET['sort2']."
";
【问题讨论】:
-
当
LEFT JOIN时,将所有右侧表条件放在ON子句中以获得真正的左连接行为。 (在 WHERE 中,您会得到常规的内部连接结果。) -
永远不要使用这个代码!!!这是一个地狱般的 SQL 注入门!首先重新考虑如何获取用户输入并对其进行验证,使用准备好的语句!!!但永远不要在查询中使用 POST 或 GET Var!
-
感谢您的建议,但这是一个实习生代码,使用它的人也可以直接更改源代码。