我有一个带有“说明”列的表“ car_purchases”。该列是一个字符串,其中包括名字的首字母缩写,后跟句号,空格和姓氏。
是“说明”列的一个示例“ J。Blow购买的汽车”
我正在使用'substring_index'函数提取'。'之前的字母。在列字符串中。像这样:
SELECT
Description,
SUBSTRING_INDEX(Description, '.', 1) as TrimInitial,
SUBSTRING_INDEX(
SUBSTRING_INDEX(Description, '.', 1),' ', -1) as trimmed,
length(SUBSTRING_INDEX(
SUBSTRING_INDEX(Description, '.', 1),' ', -1)) as length
from car_purchases;
我将此查询称为1。
picture of the result set (Result 1) is as follows
如您所见,问题是select语句中的'trimmed'列开始计算第二个定界符'',而不是从右边的第一个定界符开始,并产生结果'by J',而不仅仅是'J'。另外,length列指示字符串的长度是5而不是4,所以WTF?
但是,当我执行以下选择语句时;
select SUBSTRING_INDEX(
SUBSTRING_INDEX('Car purchased by J. Blow', '.', 1),' ', -1); -- query 2
Result ='J'作为'Result 2'。
从结果1中可以看到,“描述”列中的字符串与“结果2”中的字符串完全相同(据我所知)。但是,当对列执行substring_index(而不只是字符串本身)时,结果将忽略第一个定界符,并从字符串右边的第二个定界符中选择一个字符串。
我已经全神贯注于此,并尝试使用'by'和'by'作为分隔符,但是这两个选项都无法产生单个字符所需的结果。我不想通过使用修整函数为查询1添加更多的复杂性。我也尝试了对结果列“修剪”的强制转换功能,但仍然没有成功。我也不想这么做。
查询1的“长度”列中存在异常,如果将长度函数更改为char_length函数,如下所示:
select length(SUBSTRING_INDEX(
SUBSTRING_INDEX(Description, '.', 1),' ', -1)) as length -- result = 5
select char_length(SUBSTRING_INDEX(
SUBSTRING_INDEX(Description, '.', 1),' ', -1)) as length -- result = 4
有人可以向我解释为什么上面的select语句会产生两种不同的结果吗?我认为这就是为什么我没有得到理想结果的原因。
但是要清楚一点,我想要的结果是得到'J'而不是'by J'。
我想我可以尝试逆转,但是我不认为这是可以接受的折衷方案。另外,除了我只使用默认值以外,我对排序规则和字符集原则不熟悉。
欢呼的球员!!!!
答案 0 :(得分:0)
CHAR_LENGTH
返回以字符为单位的长度,因此具有4个2字节字符的字符串将返回4。LENGTH
但是返回以字节为单位的长度,因此具有4个2字节字符的字符串将返回8。结果中的差异(包括SUBSTRING_INDEX
)表明by
和J
之间的“空格”实际上不是单字节空间(ASCII 0x20),而是2字节字符,看起来像一个空间。要解决此问题,您可以尝试使用CONVERT
和REPLACE
用空格替换所有unicode字符。在此示例中,我在en-space
和by
之间的字符串中有一个J
Unicode字符。 CONVERT
将其更改为?
,然后REPLACE
将其转换为空格:
SELECT SUBSTRING_INDEX( SUBSTRING_INDEX("Car purchased by J. Blow", '.', 1),' ', -1)
输出:
by J
使用CONVERT
和REPLACE
:
SELECT SUBSTRING_INDEX( SUBSTRING_INDEX(REPLACE(CONVERT("Car purchased by J. Blow" USING ASCII), '?', ' '), '.', 1),' ', -1)
输出
J
对于您的查询,您可以将字符串替换为列名,即
SELECT SUBSTRING_INDEX( SUBSTRING_INDEX(REPLACE(CONVERT(description USING ASCII), '?', ' '), '.', 1),' ', -1)