web-dev-qa-db-ja.com

列内にハイフン(-)が存在するかどうかを確認する方法

CASE式で、テキスト列内を検索してハイフン(-)を識別しようとしています。

CASE 
     WHEN SUBSTRING(al.ALT_ADDRESS,1,1) IN('1','5','7') 
      AND al.NEW_ADDRESS CONTAINS '-' 
     THEN CONCAT(al.ALT_ADDRESS,al.NEW_ADDRESS)

ハイフンは列のどこにでも配置できるため、実際に列のどこにあるかに関係なく、ハイフンが存在するかどうかを知る必要があります。

私は現在 @ Joshが提供するものとまったく同じコードLIKE '%-%')を使用していますが、機能しないため機能しませんtあるべきだとわかっているいくつかの特定のインスタンスについて正しいデータを返します。 ALT_ADDRESSの正確なテキストは「2754 Churchill Circle」です。 NEW_ADDRESSの正確なテキストは「O-89421」です。ただし、返される結果にはNEW_ADDRESSは含まれません(O-89421)。

NEW_ADDRESSのダッシュが、検索(ASCII 45)を使用しているダッシュと本当に一致することを確認しました。

4
Mike Jones

既存の回答に対する別のアプローチは、存在する場合は指定された文字列の位置を返し、それ以外の場合は0を返すCHARINDEX()関数を使用することです。

select charindex('-','kevin-')

ハイフンが文字列の6番目の位置にあるため、6を返します。

select charindex('-','kevin')

文字列に「-」が存在しないため、0を返します。


John Eisbrener's 提案に従って、 PATINDEX もオプションであり、ワイルドカードを使用できます。

10
kevinnwhat

あなたが提供したコードが機能しない理由については触れませんでした。 CONTAINSは、SQL Serverの全文検索機能で使用します。これを使用しない場合は、ワイルドカードを使用したLIKE句を使用する必要があります。

CASE WHEN SUBSTRING(al.ALT_ADDRESS,1,1) IN('1','5','7') AND al.NEW_ADDRESS LIKE '%-%' 
THEN CONCAT(al.ALT_ADDRESS,al.NEW_ADDRESS)

全文検索を使用している場合でも、ダッシュを使用した照合動作は nexpected になる可能性があるため、代わりにLIKEを使用することをお勧めします。


この文字が実際にハイフンであることを再確認します。次のようなものが機能するはずです。

SELECT 
    ASCII('-') as RealHypen,
    ASCII(SUBSTRING(NEW_ADDRESS, 1, 1))
FROM YourTable
WHERE ALT_ADDRESS = '2754 Churchill Circle';

余談ですが、上記のLIKE式はSQL ServerのBツリーインデックスのシーク機能を利用できないため、大きなスキャン操作が必要な場合、大きなテーブルではパフォーマンスが低下する可能性があります。これを軽減する最良の方法(同様の状況であなたや他の人に適用する必要があります)はコンテキストに大きく依存しますが、一般的な主な代替策は次のとおりです。

  • 検索条件を評価する計算列のインデックス作成
  • トリガーを使用して検索結果を事前に永続化する
  • テキストの検索により適した外部ツールを使用する(Elasticsearchが一般的)
  • n-grams を使用(通常、3文字以上の部分文字列の場合)
  • 全文検索を使用します(これはワイルドカード自体、またはこの特定のケースでは役立ちませんが、Wordベースの検索では機能します)。

パフォーマンスの側面に興味がある場合は、フォローアップの質問をしてください。

14
Josh Darnell

LIKE '%-%'

私は現在@Joshが提供したものとまったく同じコード(LIKE '%-%')を使用していますが、それが機能することはありません。 。 ALT_ADDRESSの正確なテキストは「2754 Churchill Circle」です。 NEW_ADDRESSの正確なテキストは「O-89421」です。ただし、返される結果には、NEW_ADDRESS(O-89421)は含まれません。

私はこの問題をまったく受けません、

SELECT new_address
FROM ( VALUES
  ('O-89421')
) AS t(new_address)
WHERE new_address LIKE '%-%';

私にとってはうまくいくようです

1
Evan Carroll