我试图解决这个问题一段时间后没有找到解决方案。
我从一个装满移动设备的表中读取并列出它们,并为用户提供了搜索每个Movile设备名称和用户名列表的可能性。
这是我的代码:
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']的行仍然没有被过滤掉。
我上传了一个带有模糊名称的行为的示例图片,左边的图片是一个没有任何过滤器的选择,右图片是一个具有实际用户名的选择(模糊了,但它与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']."
";
答案 0 :(得分:1)
问题出在
行 CONCAT(tbl_user.name,' ',tbl_user.vorname) LIKE '%".$_POST['user']."%'
您在tbl_user上的LEFT JOIN将允许主查询返回,而不管该行中是否有值。但是,特定的WHERE子句行有效地覆盖了这一点;如果tbl_user.name或tbl_user.vorname为null,则结果将始终为false。
如果我需要做类似的事情,我经常将测试放入JOIN语句的ON子句中。这样它就会过滤JOINed表所在的位置,但不会导致问题。
示例查询文本应确保tbl_user在需要时进行过滤,但在没有指定任何内容时则不会过滤 -
SELECT
md.mobdev_id,
mdt.mobdev_type_bezeichnung,
m.marke_name,
u.name AS user_name,
u.vorname AS user_vorname
FROM
tbl_mobdev md
LEFT JOIN tbl_mobdev_type mdt
ON mdt.mobdev_type_id = md.mobdev_type
LEFT JOIN tbl_marke m
ON m.marke_id = mdt.mobdev_type_marke
LEFT JOIN tbl_user u
ON u.id = md.mobdev_user
AND CONCAT(u.name,' ',u.vorname) LIKE '%".$_POST['user']."%'
WHERE
CONCAT(m.marke_name,' ',COALESCE(mdt.mobdev_type_bezeichnung,''))
LIKE '%".$_POST['m.marke_name']."%'
AND md.mobdev_aktiv = '1'
ORDER BY
".$_GET['sort']." ".$_GET['sort2']."
两个旁白 -