Column Name: Name
值:
1.Praveen kumar
2.Praveen
在同一列中如果第一个单词在另一行中相同,那么我需要一个查询来提取这些名称并显示它们。
列名:ename
praveen kumar
praveen
praveen international
在这种情况下,第一行应与第二行(即praveen kumar
与praveen
进行比较,并且必须在匹配时写出第一个单词,并使用所有其他名称进行相同的处理。
我尝试的查询:
SELECT
e1.ename
e2.ename
FROM emp as e1,emp as e2
WHERE
e1.ename<e2.ename
and substring(e1.ename,1,7) = substring(e2.ename,1,7)
...但是如果我需要在数据库中比较这种类型的许多名称而不指定要比较的字符长度。如果第一个单词与另一个字段匹配,我需要这些名称。
答案 0 :(得分:1)
使用类似
的内容WITH a AS (
SELECT id
,CASE
WHEN ename not like '% %' THEN ename -- single word
ELSE Left(ename, Patindex('% %', ename) - 1) -- first word
END AS first_word
,ename
FROM emp
)
SELECT DISTINCT complete.ename
FROM a AS first
JOIN a as complete
ON first.first = complete.first
AND first.id <> complete.id -- avoid a row matching itself
这假定名称部分用空格字符分隔。
WITH
子句处理第一个单词的提取,它假设名称部分由空格字符分隔。如果规则不同,可能需要进行调整。然后在第一个单词上连接表格。
答案 1 :(得分:1)
这可能比它需要的更复杂,但这是我提出的:
基本上我使用了一个描述here的自定义函数,它将varchar分成单词。 (仔细观察,这并不完美,因为它只尊重空间和逗号,但可以很容易地扩展或替换为更复杂的东西)
然后在最终选择中,它可用于获取源集中所有选定行的所有单词,将其连接到要与之比较的目标集中的所有值的集合,但仅限于值确实开始的位置使用相同的字符串,然后将目标集中的这些值再次连接到所有提取的单词,并比较相等和位置,并在最后一步过滤那些不匹配的单词。
CREATE FUNCTION SplitWords(@text varchar(8000))
RETURNS @words TABLE (
pos smallint primary key,
value varchar(8000)
)
AS
BEGIN
DECLARE
@pos smallint,
@i smallint,
@j smallint,
@s varchar(8000)
SET @pos = 1
WHILE @pos <= LEN(@text)
BEGIN
SET @i = CHARINDEX(' ', @text, @pos)
SET @j = CHARINDEX(',', @text, @pos)
IF @i > 0 OR @j > 0
BEGIN
IF @i = 0 OR (@j > 0 AND @j < @i)
SET @i = @j
IF @i > @pos
BEGIN
-- @i now holds the earliest delimiter in the string
SET @s = SUBSTRING(@text, @pos, @i - @pos)
INSERT INTO @words
VALUES (@pos, @s)
END
SET @pos = @i + 1
WHILE @pos < LEN(@text)
AND SUBSTRING(@text, @pos, 1) IN (' ', ',')
SET @pos = @pos + 1
END
ELSE
BEGIN
INSERT INTO @words
VALUES (@pos, SUBSTRING(@text, @pos, LEN(@text) - @pos + 1))
SET @pos = LEN(@text) + 1
END
END
RETURN
END
GO
CREATE TABLE SampleSourceValues(ID INT PRIMARY KEY IDENTITY(1,1), Value VARCHAR(127))
INSERT INTO SampleSourceValues (Value)
SELECT 'First Word'
UNION
SELECT 'Second Time'
UNION
SELECT 'Yet Another Word'
GO
CREATE TABLE SampleTargetMatches(ID INT PRIMARY KEY IDENTITY(1,1), Value VARCHAR(127))
INSERT INTO SampleTargetMatches (Value)
SELECT 'Firstmispelled Word'
UNION
SELECT 'Second Time'
UNION
SELECT 'Another Word'
SELECT
--IncludedWords.pos,
--IncludedWords.value,
SampleTargetMatches.Value
FROM SampleSourceValues --select from SampleSourceValues
CROSS APPLY
(
SELECT
pos,
value
FROM dbo.SplitWords(SampleSourceValues.Value)
) AS IncludedWords -- apply word splitting to each value from SampleSourceValues
INNER JOIN SampleTargetMatches
ON CHARINDEX(IncludedWords.value, SampleTargetMatches.Value) = 1 AND IncludedWords.pos = 1
-- join rows from SampleTargetMatches that where Value starts with a word from IncludedWords that has pos = 1
CROSS APPLY
(
SELECT
pos,
value
FROM dbo.SplitWords(SampleTargetMatches.Value)
) AS IncludedWordsInTarget -- apply word splitting to each value from SampleTargetMatches
WHERE IncludedWordsInTarget.value = IncludedWords.value AND IncludedWordsInTarget.pos = 1
在结果中,您可以看到只检索到值Second Time
,因为它是唯一一个第一个单词与源值的第一个单词匹配的单词。
答案 2 :(得分:0)
select distinct t1.<Field_Name>,t2.<Field_Name>
from <Table_name> t1
inner join <Table_name> t2 on t1.<Field_Name> like t2.<Field_Name>+'%'
order by t2.<Field_Name>
希望这会对你有帮助.....
答案 3 :(得分:0)
if you want a descending order then use below :
select ename from emp order by ename;
if you want a distinct name then
select distinct ename from emp order by ename;
if you want a specific name wise search :
select ename from emp where ename like 'praveen%' order by ename