mysql - Mqsyl - 多个左连接
问题描述
我正在尝试改进在线商店管理员端的实时产品搜索。
我们目前正在使用以下查询:
SELECT p.product_id, p.full_title, p.descript, p.cost, p.no_vat, p.high_pic, p.prod_type, count(p.product_id) AS occurence, t.descript AS type_desc, p.available
FROM gdd_product as p, gdd_prodtype as t, gdd_info as i
LEFT JOIN gdd_keyword as k ON i.product_id = k.product
WHERE p.prod_type = t.prod_type
AND i.product_id = p.product_id
AND replace(concat_ws(p.descript, i.info_search1, i.info_search2, i.info_search3, k.keyword),' ','')
LIKE '%tool%'
GROUP BY p.product_id
ORDER BY occurence DESC, cost ASC LIMIT 30
这可行,但会忽略在 info_search 列中没有条目的任何结果。
所以我尝试改变它,使 gdd_info 被 LEFT JOINed,代码如下:
SELECT p.product_id, p.full_title, p.descript, p.cost, p.no_vat, p.high_pic, p.prod_type,
count(p.product_id) AS occurence, t.descript AS type_desc, p.available
FROM gdd_product as p, gdd_prodtype AS t
LEFT JOIN gdd_info as i ON p.product_id = i.product_id
LEFT JOIN gdd_keyword as k ON p.product_id = k.product
WHERE p.prod_type = t.prod_type
AND replace(CONCAT_WS(p.descript, i.info_search1, i.info_search2, i.info_search3, k.keyword),' ','')
LIKE '%tool%'
GROUP BY p.product_id
ORDER BY occurence DESC, cost ASC
LIMIT 30
...但这会引发错误:SQL 错误 (1054): Unknown column 'p.product_id' in 'on Clause'
我究竟做错了什么?
解决方案
第一个。不要将标准与 ANSI 标准(ANSI-92 与 ANSI-89)混用。使用 INNER/CROSS/LEFT 连接或,
表示法,但不能同时使用。这是不好的形式,最终可能会破裂;也许现在是什么导致了您的 p.product 错误。
SELECT p.product_id, p.full_title, p.descript, p.cost
, p.no_vat, p.high_pic, p.prod_type
, count(p.product_id) AS occurence, t.descript AS type_desc
, p.available
FROM gdd_product as p
INNER JOIN gdd_prodtype AS t
on p.prod_type = t.prod_type
LEFT JOIN gdd_info as i
ON p.product_id = i.product_id
LEFT JOIN gdd_keyword as k
ON p.product_id = k.product
WHERE replace(CONCAT_WS(p.descript, i.info_search1, i.info_search2, i.info_search3, k.keyword),' ','')
LIKE '%tool%'
GROUP BY p.product_id
ORDER BY occurence DESC, cost ASC
LIMIT 30
第二。它省略记录的原因可能是因为与字符串连接的 NULL 是 NULL。然后,您针对永远不会返回结果的 null 搜索字符串。您需要将 i.info_search1... 与空集 '' 合并, coalesce(i.info_earch1,'')
依此类推...因此它采用系列中的第一个非空值,然后将字符串与字符串进行比较
replace(CONCAT_WS(
coalesce(p.descript,'')
, coalesce(i.info_search1,'')
, coalesce(i.info_search2,'')
, coalesce(i.info_search3,'')
, coalesce(k.keyword,'')),' ','')
给我们...
SELECT p.product_id, p.full_title, p.descript
, p.cost, p.no_vat, p.high_pic, p.prod_type
, count(p.product_id) AS occurence, t.descript AS type_desc
, p.available
FROM gdd_product as p
INNER JOIN gdd_prodtype AS t
on p.prod_type = t.prod_type
LEFT JOIN gdd_info as i
ON p.product_id = i.product_id
LEFT JOIN gdd_keyword as k
ON p.product_id = k.product
WHERE replace(CONCAT_WS(
coalesce(p.descript,'')
, coalesce(i.info_search1,'')
, coalesce(i.info_search2,'')
, coalesce(i.info_search3,'')
, coalesce(k.keyword,'')),' ','')
LIKE '%tool%'
GROUP BY p.product_id
ORDER BY occurence DESC, cost ASC
LIMIT 30
这么想吧……
说 p.descript 存在,但信息不在您的左连接中...所以您将 p.descript 与 null 连接为 null。什么都不会为like
空,因此您无法获得任何记录,因为您无法对空值执行相等检查(例如)并期望得到结果。
现在说 p.descript 不存在并且为空,将它与任何为空的内容连接起来再次为空,所以你有相同的结果。
由于 concat_WS 字符串中的任何值都可能为 null,因此我们需要合并所有值以防万一。
现在我们有一个有效的字符串与您的喜欢进行比较,因此当您的字符串与您的喜欢匹配时,您现在将获得结果,而不是当您的 ws_concat 中的列值为空时擦除您的记录。
推荐阅读
- python - 激活 Python 虚拟环境并在另一个 Python 脚本中调用 Python 脚本
- android - 如何在 Kotlin 中使用 MutableLiveData?
- sql - 将单引号添加到动态 SQL
- python - 我如何遍历以逗号分隔的字符串中的每个条目,并使用 Python 将其作为单独的输入包含在内
- sql - 如何在查询中获取单行 SELECT FOR UPDATE
- simulation - Anylogic,如何动态更改生产批次的大小?
- tsql - TSQL For XML JSON AUTO 使用 CTE 和 UNION 生成平面结果
- php - 数组查询 - 转换此数组的最有效方法是什么?
- python - 增加自动缩放组的最大大小的 Lambda 问题
- javascript - 我需要推荐结构以使用 Cytoscape js