-2

国とその略語の表があり、略語で呼ばれる列と、国名を含むcode列があります。name

外国の住所を反復処理し、テーブル内で一致する単語 (つまり国) が見つかるまで各単語を検索し、case ステートメントの略語を取得する必要があります。

これはすべてのレコードに対して行われるわけではなく、作成中のファイルの 60 文字のフィールドよりも大きい特定のレコードに対してのみ行われます。

だから私がする必要があるのは、影響を与える何かです:

SELECT 
CASE WHEN address2 & foreign_address > 60
THEN split and iterate through '12345 MY SUPER LONG ADDRESS IN THE PHILIPPINES' and look up
each string until PHILIPPINES is matched in the country_codes table and 'PH' is returned
END

これは、明らかな理由でやりたくないアドレスを切り捨てることを除いて、この状況を処理するために考えることができる最良の方法です。これは、さまざまな住所や国に基づいて動的にする必要もあります。

この時点での最大の課題は、文字列を分割し、各文字列フラグメントを検索することです。

4

4 に答える 4

0
SELECT Addresses.foreign_address, Countries.Code
FROM Addresses, Countries
WHERE LEN(foreign_address) > 60
AND foreign_address LIKE '%' Countries.Name '%'

[コード] には、一致した国の略コードが含まれます。

関連する SQLFiddle (および以下の完全なコード) は次のとおりです

CREATE TABLE Countries (Name varchar(128), Code varchar(2));

CREATE TABLE Addresses (foreign_address varchar(512));

INSERT INTO Countries(Name,Code) VALUES('PHILIPPINES', 'PH'); 

INSERT INTO Addresses(foreign_address)
VALUES('12345 MY SUPER LONG ADDRESS IN THE PHILIPPINES UNTIL PHILIPPINES IS MATCHED AND PH IS RETURNED');

SELECT Addresses.foreign_address, Countries.Code
FROM Addresses, Countries
WHERE LEN(foreign_address) > 60
AND foreign_address LIKE '%' + Countries.Name + '%'
于 2013-08-19T21:35:53.900 に答える
-2

私は SQL Server でこのスタイルのプログラミングを推奨しているわけではありませんが、これはあなたが求めたことを実行する方法です。まず、テーブル変数で文字列を 1 つの単語にトークン化します。次に、テーブル変数でカーソルを開き、単語をループして、breakdbo.countries から結果が見つかった場合に呼び出します。ループは SQL Server では非常に非効率的であることに注意してください。UDF テーブル関数はここから来ました: How to split a string in T-SQL?

-- Create the UDF
CREATE FUNCTION Splitfn(@String varchar(8000), @Delimiter char(1))       
returns @temptable TABLE (items varchar(8000))       
as       
begin       
    declare @idx int       
    declare @slice varchar(8000)       

    select @idx = 1       
        if len(@String)<1 or @String is null  return       

    while @idx!= 0       
    begin       
        set @idx = charindex(@Delimiter,@String)       
        if @idx!=0       
            set @slice = left(@String,@idx - 1)       
        else       
            set @slice = @String       

        if(len(@slice)>0)  
            insert into @temptable(Items) values(@slice)       

        set @String = right(@String,len(@String) - @idx)       
        if len(@String) = 0 break       
    end   
return      

end

go
-- Create the dbo.countries table so we can test our code later
create table dbo.countries (code char(2), name varchar(100))
go
-- Insert one record in dbo.countries so we can test our code later
insert into dbo.countries (code, name)
select 'PH', 'PHILIPPINES'
go
-- for one @String input, this is what I would do
declare @String varchar(1000) = '12345 MY SUPER LONG ADDRESS IN THE PHILIPPINES'
declare @CountryCode char(2) = ''
declare @done bit = 0x0
declare @word varchar(1000)

declare @words table (word varchar(250) primary key)

-- Break apart your @String into a table of records, only returning the DISTINCT values.  
-- Join on the domain list so we can only process the ones that will return data in the CURSOR (eliminating excess looping)
insert into @words (word)
--
select  distinct items as word
from    dbo.Splitfn(@String, ' ') s
join    dbo.countries c 
on      lower(c.name) = lower(s.items)

declare word_cursor CURSOR for
select  word
from    @words w

open word_cursor

fetch next from word_cursor into @word 

while @@FETCH_STATUS = 0
begin
    select      @CountryCode = code
    from        dbo.countries
    where       name = @word

    if @@trancount > 0
    begin
        break
    end

    fetch next from word_cursor into @word 
end

-- clean up the cursor
close word_cursor
deallocate word_cursor

-- return the found CountryCode
select @CountryCode
于 2013-08-19T23:27:09.770 に答える