如何在列中找到第二个值
Posted
技术标签:
【中文标题】如何在列中找到第二个值【英文标题】:How to find second value inside a column 【发布时间】:2016-04-09 08:54:46 【问题描述】:如何列出所有姓氏相同的乐队成员的姓名?
该列具有这样的值
band_NAME
-------------------
Carla Thomas
Stephen E. Rice
Cynthia P. Tree
Richard Anthony Paul
Ann Frances Smith
Lorace Black
Timothy Adam Paul
我知道我们必须使用instr
和substr
。我只是不明白我们将如何确定位置。
我知道基本格式会是这样的
SELECT band_NAME
FROM TABLE
where substr(band_name, ?, instr( ) IN
(select substr(band_name, ?, instr( )-1)
from table
group by SUBSTR(band_NAME , ?, INSTR( )-1 )
HAVING COUNT(* ) > 1 );
但是问号和instr
里面是什么?
不胜感激!
【问题讨论】:
这应该如何工作?在“Jerry Lee Lewis”中,名字是“Jerry Lee”,姓氏是“Lewis”,所以你先分开,姓在最后一个空格。在“Gabriel García Márquez”中,名字是“Gabriel”,姓氏是“García Márquez”,即您在第一个空格处分开。也有像“Juan Luis García Perales”这样的名字,它既不是第一个也不是最后一个空格将名字和姓氏分开。再想想中文名字,姓在哪里。 是的,我不明白如何拆分它。上面列出的一些名字有一个中间的首字母,所以可以在句号之后分开,但至于其他三个名字,我不知道我会怎么做。只需要找出一种方法来找到姓氏的匹配项并显示它们 我的意思是,您不能仅从全名推导出什么是名字和什么是姓氏。你必须有更多的信息。可能是一本名字和姓氏的字典。 (即便如此,“保罗”既可以是名字也可以是姓氏)。也许你可以妥协。但是,接下来由您来定义您可以接受的规则。 好吧,还有几列相关联,但它们都不能确定名字/姓氏是什么... 【参考方案1】:我假设您的名字和姓氏之间的分隔符是一个空格。字符串中的更多空格是姓氏的一部分。因此,您可能想要搜索第一个空格字符。
返回子字符串第一次出现的位置instr(str, substr)
。
然后,使用substring(str, pos)
返回从给定位置开始的子字符串(由 instr 函数提供)。
SELECT substring(band_name, instr(band_name, ' '))
FROM yourtable
【讨论】:
我在发布问题之前尝试过这个尝试,但不幸的是它不能正常工作:( @Bob:这并没有告诉考虑我什么。 “不幸的是它不能正常工作”是什么意思? 对不起,我完全是初学者。当我尝试上面的代码时,它说“无效”.. @Bob,这不会让我复制任何东西。在您的问题中附上所需的结果。 . .此外,您一直在尝试的完整代码和错误。【参考方案2】:试试这个:
SELECT t1.band_NAME
FROM TABLE t1 LEFT JOIN TABLE t2
ON SUBSTRING_INDEX(t1.band_name, ' ', - 1) = SUBSTRING_INDEX(t2.band_name, ' ', - 1)
WHERE t1.band_name <> t2.band_name
这就像你的伪代码 MySQL:
SELECT band_NAME FROM TABLE
Where FIND_IN_SET (SUBSTRING_INDEX(band_name, ' ', -1),
(Select SUBSTRING_INDEX(band_name, ' ', -1) bn
From TABLE Group by bn
having Count(bn) > 1
)
)
SQL 服务器
SELECT band_NAME FROM TABLE
Where
SUBSTRING(band_NAME, CHARINDEX(' ', band_NAME) + 1, LEN(band_NAME)) AS [Last Name]
IN
(Select SUBSTRING(band_NAME, CHARINDEX(' ', band_NAME) + 1, LEN(band_NAME)) AS [Last Name]
From TABLE Group by [Last Name] -- or SUBSTRING(band_NAME, CHARINDEX(' ', band_NAME) + 1, LEN(band_NAME)) AS [Last Name]
having Count(*) > 1
)
)
此外,我认为您可以通过某种方式从STRING_SPLIT 中受益
【讨论】:
我试过了,它对我很好,你能确保括号正确关闭吗?你用你的真实表名在两个地方更改TABLE
? @鲍勃
您的确切查询显示“sql 命令意外结束”。我正在使用 sql developer,如果这有什么不同的话..?它不识别“子字符串索引”,所以我在添加另一个括号后将其替换为 substr 。然后它说“bn”是一个“无效的运算符——不存在”。
哦,你用mysql
@Bob 标记了你的问题
@Bob 对不起,我没有 sql server
,所以我尝试按预期写,尝试编辑后的答案并告诉我
使用更新的代码表示无效的关系运算符。我尝试了两种方式。 Sql 开发人员无法识别“len”,因此我将其更改为长度。还将 substring 更改为 substr,并将 charindex 更改为 instr。不明白为什么它不起作用...【参考方案3】:
试试这个
with cte as
(
select band_name, ROW_NUMBER() over(partition by SUBSTRING(band_name,CHARINDEX(' ',band_name),LEN(band_name)) order by band_name) as cnt,
SUBSTRING(band_name,CHARINDEX(' ',band_name),LEN(band_name)) as lastname
from your_table
)
select band_name
from cte
where lastname in (select lastname from cte where cnt > 1)
【讨论】:
【参考方案4】:好的,
最好的解决方案是更改架构并将姓氏存储在单独的列中。
同时你可以得到这样的姓氏,
SELECT
[band_NAME],
CASE WHEN CHARINDEX(' ', [band_NAME]) > 0
THEN
RIGHT([band_NAME], CHARINDEX(' ', REVERSE([band_NAME])))
ELSE
[band_NAME]
END [LastName]
FROM
[TABLE]
然后你可以像这样对它们进行分组
SELECT
[LastName],
COUNT(*)
FROM
(
SELECT
[band_NAME],
CASE WHEN CHARINDEX(' ', [band_NAME]) > 0
THEN
RIGHT([band_NAME], CHARINDEX(' ', REVERSE([band_NAME])))
ELSE
[band_NAME]
END [LastName]
FROM
[TABLE]
) [TABLEWithLastName]
GROUP BY
[LastName];
【讨论】:
以上是关于如何在列中找到第二个值的主要内容,如果未能解决你的问题,请参考以下文章
我在列中有几个扩展的小部件。首先我展开一个小部件。当我展开第二个时,第一个应该自动折叠