比较字符串数据和表数据

时间:2009-08-24 19:29:29

标签: sql-server-2005

我有一个包含字符串值的表,需要单独匹配一列。例如

表A

Col1    col2
 1234   0029QS, 0029QT, 0029QU, 0029QV
 2222   0006AG_0042
 2343   0032BP, 0032BQ, 0032BR
 1232   5000_0708, 5000_0709, 5000_0710

表B

0029QS
0032BQ
0006AG_0042
5000_0709

我需要能够匹配并从Table A.Col1中提取记录以获得TableA.col2 = TableB.col1

的匹配

sql如下:

Create Table TableA(Col1 int , Col2 varchar(max) )
INSERT INTO TableA
Select   1234, '029QS, 0029QT, 0029QU, 0029QV'
 INSERT INTO TableA
Select   2222, '0006AG_0042'
 INSERT INTO TableA
Select   2343,   '0032BP, 0032BQ, 0032BR'
 INSERT INTO TableA
Select   1232,  '5000_0708, 5000_0709, 5000_0710'

Go

Create table TableB(Col2 Varhcar(50) )
INSERT INTO TableB
Select '0029QS'
INSERT INTO TableB
Select '0032BQ'
INSERT INTO TableB
Select '0006AG_0042'
INSERT INTO TableB
Select '5000_0709'
INSERT INTO TableB
Select '5000_0710'
GO

2 个答案:

答案 0 :(得分:2)

您最好的选择是规范化表格,因此TableA每个Col2数据会有一行。然后,您可以非常轻松快速地加入表格。如果不这样做,您可以尝试以下方法:

在使用我的功能之前,您需要设置一个“帮助程序”表,每个数据库只需执行一次这样的操作:

CREATE TABLE Numbers
(Number int  NOT NULL,
    CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number ASC)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
DECLARE @x int
SET @x=0
WHILE @x<8000
BEGIN
    SET @x=@x+1
    INSERT INTO Numbers VALUES (@x)
END

使用此函数来分割您的字符串,该字符串不会循环且非常快:

CREATE FUNCTION [dbo].[FN_ListToTable]
(
     @SplitOn              char(1)              --REQUIRED, the character to split the @List string on
    ,@List                 varchar(8000)        --REQUIRED, the list to split apart
)
RETURNS
@ParsedList table
(
    ListValue varchar(500)
)
AS
BEGIN

/**
Takes the given @List string and splits it apart based on the given @SplitOn character.
A table is returned, one row per split item, with a column name "ListValue".
This function workes for fixed or variable lenght items.
Empty and null items will not be included in the results set.


Returns a table, one row per item in the list, with a column name "ListValue"

EXAMPLE:
----------
SELECT * FROM dbo.FN_ListToTable(',','1,12,123,1234,54321,6,A,*,|||,,,,B')

    returns:
        ListValue  
        -----------
        1
        12
        123
        1234
        54321
        6
        A
        *
        |||
        B

        (10 row(s) affected)

**/



----------------
--SINGLE QUERY-- --this will not return empty rows
----------------
INSERT INTO @ParsedList
        (ListValue)
    SELECT
        ListValue
        FROM (SELECT
                  LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue
                  FROM (
                           SELECT @SplitOn + @List + @SplitOn AS List2
                       ) AS dt
                      INNER JOIN Numbers n ON n.Number < LEN(dt.List2)
                  WHERE SUBSTRING(List2, number, 1) = @SplitOn
             ) dt2
        WHERE ListValue IS NOT NULL AND ListValue!=''



RETURN

END --Function FN_ListToTable

您可以在此查询中使用此功能来解决您的问题......

select
    a.Col1,b.Col2,a.Col2,b.Col2
    FROM TableA  a
    INNER JOIN TableB b On b.Col2 IN (SELECT ListValue FROM dbo.FN_ListToTable(',',a.Col2))

输出

Col1        Col2          Col2                           
----------- ------------- -------------------------------
2222        0006AG_0042   0006AG_0042                    
2343        0032BQ        0032BP, 0032BQ, 0032BR         
1232        5000_0709     5000_0708, 5000_0709, 5000_0710
1232        5000_0710     5000_0708, 5000_0709, 5000_0710

修改
尝试一下,它可能会更快:

select
    a.Col1,b.Col2,a.Col2
    FROM TableA                                     a
        CROSS APPLY dbo.FN_ListToTable(',',a.Col2)  a2 
        INNER JOIN TableB                           b On a2.ListValue=b.Col2

如果要标准化表格,请执行以下操作:

Create Table TableA2(Col1 int , Col2 varchar(50) )

不要忘记在Col2上创建索引

INSERT INTO TableA2
SELECT
    a.Col1, b.ListValue
    FROM TableA  a
        CROSS APPLY dbo.FN_ListToTable(',',a.Col2) b 

现在找到匹配项:

SELECT
    a.*
    FROM TableA2           a
        INNER JOIN TableB  b ON a.Col2=b.Col2

完成更改,如果需要,可以删除TableA表,然后将TableA2重命名为TableA

答案 1 :(得分:0)

您可以使用col2值对表进行规范化,因此它更像是:

Col1    col2
1234   0029QS
1234   0029QT
1234   0029QU
1234   0029QV
2222   0006AG_0042
2343   0032BP
2343   0032BQ
2343   0032BR

然后你可以在col2和table b上进行内连接