如何使用SQL检查一列的字符是否与另一列匹配

时间:2014-01-21 08:50:26

标签: sql

Column Name: Name

值:

1.Praveen kumar

2.Praveen

在同一列中如果第一个单词在另一行中相同,那么我需要一个查询来提取这些名称并显示它们。

列名:ename

        praveen kumar
        praveen
        praveen international

在这种情况下,第一行应与第二行(即praveen kumarpraveen进行比较,并且必须在匹配时写出第一个单词,并使用所有其他名称进行相同的处理。

我尝试的查询:

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)

...但是如果我需要在数据库中比较这种类型的许多名称而不指定要比较的字符长度。如果第一个单词与另一个字段匹配,我需要这些名称。

4 个答案:

答案 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分成单词。 (仔细观察,这并不完美,因为它只尊重空间和逗号,但可以很容易地扩展或替换为更复杂的东西)

然后在最终选择中,它可用于获取源集中所有选定行的所有单词,将其连接到要与之比较的目标集中的所有值的集合,但仅限于值确实开始的位置使用相同的字符串,然后将目标集中的这些值再次连接到所有提取的单词,并比较相等和位置,并在最后一步过滤那些不匹配的单词。

Fiddle to try out

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