2010-11-19 7 views
5

varcharとして保存されている電話番号を削除する必要があります。不明な電話番号が1桁のシーケンスとして格納されている不良データがあります。最終的にもっと複雑な(市外局番&接頭辞マッチング)が行われますが、私は明らかに悪いレコードに単純なクエリをします。例えばのでT-SQL単一の繰り返し文字/数字で構成されるvarcharフィールドを識別するクエリ?

有効な電話番号:3289903829

無効な電話番号:1111111111

偽のプロダクトIDが適切な長さ(10桁)がある場合、今では解析が簡単で、クリーン。

SELECT phone 
    FROM customers 
    SET phone = NULL 
    WHERE phone IN ('0000000000','9999999999',''8888888888','7777777777','6666666666','5555555555','4444444444','3333333333','2222222222','1111111111') 

ただし、偽の電話機は、(実際にはタイプミスの可能性があります)11個、9個、またはn個の場合があります。
同じ文字/数字のすべてで構成されるID文字列はどのようにすることができますか?

1111111 - match 
4444 - match 
1112 - no match 
4445555 - no match 

答えて

10

あなたは最初の文字を取得し、それを複製することができます。

where phone = replicate(left(phone,1), len(phone)) 
    and phone is not null 
+3

'substring(phone、1,1)'ではなく 'left(phone、1)'を使うこともできます。 –

+0

@マーク、ありがとうございますあなたのコメント –

+0

@ adriftは(電話、1)よりも速く(電話、1)残っていますか?ちょっと興味があるんだけど。 –

1

はたぶん、あなたはこれを行うには、SQL関数を作成することができます。

私はそれの根性はこのようなものに見えると思います:あなたはそれを実行する必要がどのくらいの速に応じて

DECLARE @field varchar(10) 
SET @field = '11111' 

DECLARE @len INT 
SET @len = LEN(@field) 

DECLARE @counter INT 
SET @counter = 1 

DECLARE @firstChar VARCHAR(1) 
SET @firstChar = NULL 

DECLARE @currentChar VARCHAR(1) 
SET @currentChar = NULL 

DECLARE @allSameNumber BIT 
SET @allSameNumber = 1 

WHILE @counter <= @len AND @allSameNumber = 1 BEGIN 

    SET @currentChar = SUBSTRING(@field,@counter,1) 
    IF @firstChar IS NULL BEGIN 
     SET @firstChar = @currentChar 
    END 
    IF NOT ISNUMERIC(@currentChar) = 1 OR NOT @currentChar = @firstChar BEGIN 
     SET @allSameNumber = 0 
    END 
    SET @counter = @counter + 1 

END 

SELECT @allSameNumber 
+0

言われているように、複製ソリューションははるかにエレガントです!私はおそらくそれに行くだろう。 – Brandon

3

を、あなたの他のオプションは、一時テーブルを移入し、それに電話番号を参加することです。複数回実行している場合は、実テーブルを作成して、実行ごとに再作成する必要はありません。速くするために、フィールドのインデックスを作成することもできます。あなたの5月のマイルは、あなたが比較しなければならないレコードの数と比較するのに必要な速さで変わることがあります。

CREATE TABLE #Numbers 
(
    PhoneNumber VARCHAR(13) NOT NULL 
) 

DECLARE @run BIT 
SET @run = 1 

DECLARE @number INT 
SET @number = 1 

DECLARE @Counter INT 
SET @Counter = 1 

WHILE(@run = 1) 
BEGIN 

WHILE(@Counter < 13) 
BEGIN 
    INSERT INTO #Numbers 
    SELECT REPLICATE(@number,@counter) 

    SET @Counter = @Counter + 1 
END 


SET @Counter = 1 
SET @number = @number + 1 

IF(@number > 9) 
BEGIN 
    SET @run = 0 
END 

END 

SELECT * FROM Phone p JOIN #numbers n ON p.PhoneNumber = n.PhoneNumber 

このようにして、フィールドを再計算する必要はありません。この場合、フィールドの数値を毎回比較しています。

+0

これらの「特別な」電話番号の長さが変わるので、 '13 'の代わりに' select max(len(phone)) 'を使用してクエリを実行するとよいでしょう。 –

+1

これは良い点ですが、実際には電話番号が変更され、最長の電話番号が更新される可能性があるため、実際にはテーブルのフィールドの長さを調べます。テーブルを見ると、それよりも長い電話番号はないことがわかります。 – kemiller2002

+0

すてきな解決策。+1私の場合は「一度」のクリーンアップなので、よりシンプルな方法を使いました。私は無効なデータを防ぐための制約を置いています。あなたの方法は、定期的なデータのスクラブを必要とする人にとって、より良い解決策になります。 –

関連する問題