从SQL Server中的varchar列中提取名称

时间:2015-11-17 09:48:17

标签: sql sql-server database tsql varchar

对我来说这是一个简单的测试,我无法找到任何解决方案。

我的下表名称为 summary user

+----+--------------------------------------------------------------------------------------------+
| id |                                          summary                                           |
+----+--------------------------------------------------------------------------------------------+
|  1 | asdffgggggg Anand   * edkkofffmfmmfmfm Bala          sdkdodkekeke Chandra dkkdkd "vinoth"* |
|  2 | asdffgggggg Dinesh  * edkkofffmfmmfmfm Frankin       sdkdodkekeke Elisia  dkkdkd  Ganesh.  |
|  3 | asdffgggggg Hansika  edkkofffmfmmfmfm [A.Ishwariya]* sdkdodkekeke Jack    dkkdkd "Lalitha" |
+----+--------------------------------------------------------------------------------------------+

+----+-------------+
| id |    name     |
+----+-------------+
|  1 | A.Ishwariya |
|  2 | Anand       |
|  3 | Bala        |
|  4 | Chandra     |
|  5 | Dinesh      |
|  6 | Elisia      |
|  7 | Frankin     |
|  8 | Ganesh      |
|  9 | Hansika     |
| 10 | Jack        |
| 11 | Lalitha     |
| 12 | Vinoth      |
+----+-------------+
  • 我希望摘要列中的所有名称都以*
  • 结尾

输出1:

╔════╦═════════════╗
║ id ║    name     ║
╠════╬═════════════╣
║  1 ║ Anand       ║
║  1 ║ Vinoth      ║
║  2 ║ Dinesh      ║
║  3 ║ A.Ishwariya ║
╚════╩═════════════╝
  • 我希望摘要列中的所有名称都以[{1}}
  • 结尾

输出2:

*

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

为了创造答案,我设法缺乏一些细节。 如果我们猜测数据是这种格式

public class MyMain
{
   public static void main(String args[])throws Exception {
      //working fine
      System.out.println(TestEnum.AccountState.NEW);

      // But When I create object for TestEnum by using new ,It's throw error  message

      System.out.println(new TestEnum().AccountState.NEW);
   }
}

我们首先需要以这种方式清理那些混乱的数据:

Create table dbo.[Summary]
(
   id int not null
  ,summary varchar(2000) not null
)
GO

insert into dbo.[Summary] 
values
  (1, 'asdffgggggg Anand   * edkkofffmfmmfmfm Bala          sdkdodkekeke Chandra dkkdkd "vinoth"*')
 ,(2, 'asdffgggggg Dinesh  * edkkofffmfmmfmfm Frankin       sdkdodkekeke Elisia  dkkdkd  Ganesh')
 ,(3, 'asdffgggggg Hansika  edkkofffmfmmfmfm [A.Ishwariya]* sdkdodkekeke Jack    dkkdkd "Lalitha"')
 GO

现在我们摆脱了额外的空间和特殊的字符。我们需要计算空间。

Obs:我猜测数据的“结构”是不变的。 当然可以处理变体结构(例如每行中变体的名称数量),但这很复杂,可能需要递归,循环等。

update s
set s.summary = replace(s.summary,'[','')
 from dbo.[Summary] s

update s
set s.summary = replace(s.summary,']','')
 from dbo.[Summary] s

update s
set s.summary = replace(s.summary,'"','')
 from dbo.[Summary] s


while exists(
 select *
 from dbo.[Summary] s
 where charindex('  ',s.summary) > 0
)
begin
    update s
    set s.summary = replace(s.summary, '  ',' ')
    from dbo.[Summary] s
end

update s
set s.summary = replace(s.summary, ' *','*')
from dbo.[Summary] s

最后,我们可以找到所有分隔名称的空格,并使用它来提取名称(和姓氏?)

这会产生所需的输出

修改

我在OP发布USER表之前构建此解决方案。在这里,我只是处理糟糕的格式化数据并使用字符串进行播放。

使用该USER表可以更轻松地完成任务。只需选择每个名称并在摘要中进行搜索。

答案 1 :(得分:0)

你走了。 SQL小提琴:http://sqlfiddle.com/#!3/c4b9e/1

CREATE FUNCTION [dbo].[SplitString]
(
   @CSVString NVARCHAR(MAX),
   @Delimiter NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING AS
RETURN
   WITH E1(N)        AS ( SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 
                     UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 
                     UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1),
   E2(N)        AS (SELECT 1 FROM E1 a, E1 b),
   E4(N)        AS (SELECT 1 FROM E2 a, E2 b),
   E42(N)       AS (SELECT 1 FROM E4 a, E4 b),
   cteTally(N)  AS (SELECT 0 
                    UNION ALL 
                    SELECT TOP (DATALENGTH(ISNULL(@CSVString,1))) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E42),
   cteStart(N1) AS (SELECT t.N+1 
                    FROM cteTally t
                     WHERE (SUBSTRING(@CSVString,t.N,1) = @Delimiter OR t.N = 0))
    SELECT Item = SUBSTRING(@CSVString, s.N1, ISNULL(NULLIF(CHARINDEX(@Delimiter,@CSVString,s.N1),0)-s.N1,8000))
FROM cteStart s;

CREATE TABLE Summary (Id INT, Summary NVARCHAR(4000))
CREATE TABLE [User] (NAME NVARCHAR(50))

INSERT INTO Summary (Id,Summary)
SELECT 1,'asdffgggggg Anand   * edkkofffmfmmfmfm Bala          sdkdodkekeke Chandra dkkdkd "vinoth"*'
UNION ALL
SELECT 2,'asdffgggggg Dinesh  * edkkofffmfmmfmfm Frankin       sdkdodkekeke Elisia  dkkdkd  Ganesh.'
UNION ALL
SELECT 2,'asdffgggggg Hansika  edkkofffmfmmfmfm [A.Ishwariya]* sdkdodkekeke Jack    dkkdkd "Lalitha"'

INSERT INTO [User] (Name)
SELECT 'Anand'
UNION ALL
SELECT 'Vinoth'
UNION ALL
SELECT 'Dinesh'
UNION ALL
SELECT 'A.Ishwariya'

这是您从摘要列返回具有*:

的名称的查询
SELECT 
Data.Id,Summ
FROM 
(SELECT Id,Item
,REPLACE(REPLACE(REPLACE(SUBSTRING(RTRIM(item),LEN(RTRIM(item)) + 2 - CHARINDEX(' ',REVERSE(RTRIM(item))),4000),'"',''),'[',''),']','') Summ
FROM Summary 
CROSS APPLY (SELECT item FROM SplitString(Summary,'*')) Map) Data
INNER JOIN [User] ON Data.Summ = Name

作为旁注,如果您可以将摘要列中的数据存储在多个列而不是一列中,那么这将更加简单。