MySQL 拆分字符串函数 SPLIT_STR 不适用于 LEFT JOIN。有啥问题吗?

Posted

技术标签:

【中文标题】MySQL 拆分字符串函数 SPLIT_STR 不适用于 LEFT JOIN。有啥问题吗?【英文标题】:MySQL Split String Function SPLIT_STR does not work with LEFT JOIN. Any issue?MySQL 拆分字符串函数 SPLIT_STR 不适用于 LEFT JOIN。有什么问题吗? 【发布时间】:2012-01-02 20:58:51 【问题描述】:

创建 mysql 拆分字符串函数SPLIT_STR fedecarg.com/.../mysql-split-string-function/

CREATE FUNCTION SPLIT_STR(
  x VARCHAR(255),
  delim VARCHAR(12),
  pos INT
)
RETURNS VARCHAR(255)
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
       LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1),
       delim, '');

运行 SQL:

SELECT t.en AS `type`, SPLIT_STR(l.en, ',', 1) AS city,
SPLIT_STR(l.en, ',', 2) AS country
FROM table1
JOIN table2
USING ( id )
LEFT JOIN table3 AS t ON table1.type = t.id
/* the next line has failure with SPLIT_STR */
LEFT JOIN table3 AS l ON table1.location = l.id
WHERE language.lang =  'en'
AND language.url =  'europe-countries'
LIMIT 1;

表1

id               | type            | location
-----------------+-----------------+-----------------
6BC45C02         | place           | london,england

表2

id               | url
-----------------+-----------------
6BC45C02         | europe-countries

表3

id               | en
-----------------+-----------------
london           | London
england          | England

失败结果:

type             | city            | country
-----------------+-----------------+----------------
place            | NULL            | NULL

预期的结果是返回citycountry

type             | city            | country
-----------------+-----------------+-----------------
place            | London          | England

关于检查 SPLIT_STR 是否正在使用简单的 SQL:

SELECT SPLIT_STR(location, ',', 1) AS city, SPLIT_STR(location, ',', 2) AS contry
FROM table1
WHERE id =  '6BC45C02'
LIMIT 1;

它返回很好的结果:

city             | contry
-----------------+-----------------
london           | england

【问题讨论】:

你确定你得到了结果吗?如果你把你现在的SELECT改成这个SELECT t.en AS [type], l.en会怎么样? 另外(但不是真正的问题),您应该将SPLIT_STR(l.en, ',', 1) AS country 更改为SPLIT_STR(l.en, ',', 2) AS country 在某些情况下,左连接会导致您的函数无法处理的空值。但更糟糕的是,除非你的例子搞砸了, Table1.type value 'Place' table3.id value 'london' 所以你得到空值。 table3 的问题仍然存在,因为 l 以值 'london,england' 'london' 或 'england' 的身份加入,你应该在国家/地区的选择中也有 2。 另外,你在 table3 上做的连接没有任何意义,iden 是一样的。您正在对 en 字段应用拆分,但该字段的值已经拆分 @Lamak - SELECT t.en AS [type], l.en 不起作用。感谢您在问题中提到SPLIT_STR(l.en, ',', 2) AS country - 我更新了它。 【参考方案1】:

也许这...但性能会很糟糕。

SELECT T1.type,
  SPLIT_STR(t.en, ',', 1) AS city,
  SPLIT_STR(l.en, ',', 2) AS country
FROM table1 t1
INNER JOIN table2 t2 
  ON T1.ID = T2.ID
LEFT JOIN table3 t 
  ON t.id = SPLIT_STR(t1.location, ',', 1)
LEFT JOIN table3 l 
  ON l.id = SPLIT_STR(t1.location, ',', 2)
WHERE t2.url = 'europe-countries'
LIMIT 1;

这会更好,因为它不需要调用函数 4 次:(使用合并来确定函数是否按预期工作将返回正确的大小写,然后是小写,如果它没有按预期工作,则函数中断)

SELECT InTable.Type, 
   coalesce(t.en, inTable.City, 'FunctionBroke') as city, 
   coalesce(l.en, intable.country, 'FunctionBroke2') as country
FROM 
    (SELECT t1.type,
      SPLIT_STR(T1.Location, ',', 1) AS City,
      SPLIT_STR(T1.Location, ',', 2) AS Country
    FROM table1 T1
    INNER JOIN table2 T2 
      ON T1.ID = T2.ID 
        AND t2.url='europe-countries'
    ) InTable
LEFT JOIN table3 t 
  ON InTable.City = t.id
LEFT join table3 l 
  ON InTable.Country = l.id
LIMIT 1;

更好的存在:表 3 的唯一目的是正确区分城市/国家名称吗? UDF(用户定义函数)的唯一目的是拆分值吗?

EDIT 1 Fixed first 应该是 t.en 而不是 l.en 在第一个左边 加入。 EDIT 2 Fixed 2nd 应该是 t1 (这是复制和粘贴 你) 编辑 3 重新审视了两个响应中的所有内容,复制了 OP 中的一些错误

【讨论】:

对于您的第二个 SQL,我收到错误 #1054 - Unknown column 'l.en' in 'field list' 您的第一个更新的 SQL 返回查询仅针对 type=>地点,对于 citycountry 返回 NULL。 谢谢,xQbert!您的第一个 SQL(查询耗时 0.0011 秒)返回 type:place、city:London 和 country 的空查询。第二条 SQL(查询耗时 0.0009 秒)工作正常并返回预期结果 type:place、city:London 和 country:England。【参考方案2】:

据我所见,SPLIT_STR(l.en, ',', 1) 将始终为 nulltable3.en 中没有可拆分的内容)此外,表 table1.location = l.id 的连接条件对于您的数据始终为 false(london 和 @987654326 都不是@ 等于 london,england)。

根据您发布的所需输出,我认为您正在寻找类似(我不确定 language.url = 'europe-countries' 是什么,我在问题中没有看到名为“语言”的表或别名,所以我只是忽略了它)

SELECT t1.`type` AS `type`, 
MAX(CASE WHEN t3.id = SPLIT_STR(t1.location, ',', 1) THEN t3.en END) as `city`,
MAX(CASE WHEN t3.id = SPLIT_STR(t1.location, ',', 2) THEN t3.en END) as `country`
FROM table1 t1
INNER JOIN table2 t2 ON (t2.id = t1.id)
LEFT JOIN table3 t3 ON 
 (t3.id = SPLIT_STR(t1.location, ',', 1) OR t3.id = SPLIT_STR(t1.location, ',', 2))
GROUP BY t1.`type`

更新(l.en 替换为t1.location

【讨论】:

返回错误#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM table1 t1 INNER JOIN table2 t2 ON (t2.id = t1.id) LEFT JOIN table3 t' at line 4 会遇到类似的问题我是 l.en 不是别名表名。 抱歉打印错误,country 后面有多余的逗号 ... 修复中 我也忘记在LEFT JOIN 条件下关闭圆括号...已修复。 您最近更新的 SQL 返回错误#1054 - Unknown column 'l.en' in 'field list'

以上是关于MySQL 拆分字符串函数 SPLIT_STR 不适用于 LEFT JOIN。有啥问题吗?的主要内容,如果未能解决你的问题,请参考以下文章

mysql中如何拆分查询?如图所示。

MySQL 直接用SQL分割字符串到数组

如何在mysql中拆分名称字符串?

Mysql 函数确定性错误

MySQL数据库,字符串字段拆分

拆分字符串并循环遍历 MySql 过程中的值