2012-03-30 17 views
1

varcharカンマ区切りで格納されたIDを持つすべての行をデータベースから選択する方法を教えてください。たとえば、次のような表があります。IDをコンマ区切りの値として格納する

, 7, 9, 11 

これらのIDを持つ行を選択するにはどうすればよいですか。

+5

ますそれらのIDを別のテーブルに分割することを検討したいかもしれません。コンマ区切りの値としてそれらを保存することは、維持することの悪夢となります。 –

+2

パフォーマンスも問題になります。これはデータベースにデータを格納する方法ではありません。 – datagod

+0

また、エラーが発生しやすくなります。整数を格納すると、結果は常に同じになります。しかし、文字列を格納するときに "7"を検索すると、 "7.0"または "7(スペース)"と同じ結果が得られません。テーブルを正規化するための+1。 – Leigh

答えて

0
select * from table_name where id in (7, 9, 11) 

通常は最初にコンマを使用する場合は、まずコンマを削除する必要があります。

+1

これは機能しません - IDをCSV形式で1列に格納しています。 –

+1

完全に間違っています。 csvsはVarcharにあります。 – shashankaholic

+0

指摘したように、データがどのように格納されているかによって、これは機能しません。 –

1

あなたは2つのオプションがあります:

  1. 一時テーブルに文字列を分割し、その一時テーブルからテーブルあなたの選択に参加する機能を使用します。
  2. idを(@変数)のテーブルに照会するために動的SQLを使用します。この方法を選択すると悪い選択です。 ( '7,9,11')に対する
0

使用一致(列)

これは7,9,11があり、あなたのIDのすべてのvarchar列を示しwilll。 しかし、あなたはurカラムがfulltextインデックスを持つようにしなければなりません。

+0

その場合に(9、7、11)を検索するとどうなりますか? –

+0

と一致すると、カンマ区切りの値がすべて別個に一致するため、同じ結果になります。 –

3

データベースを正規化します。最も可能性の高いルックアップテーブルを使用する必要があります。

+0

ルックアップテーブルが何を意味するのかよく分かりません。 – Computerman1597

+3

あなたは、PK参照とあなたが上に持っている個々の値の行を持つテーブルを持っているはずです。 7,9,11はデータベース内の3つの別々のレコードとしてリストされます(別の表にあります) –

0

私はここに古いアプリケーションのバグを修正し、彼らはこのようにそれを扱っどこ見たちょうど昨日:私はあなたが7を含む可能性のあるデータベースからServiceIDsの値のようなものを言っていると仮定しています

AND (T.ServiceIDs = '#SegmentID#' OR T.ServiceIDs LIKE '#SegmentID#,%' 
       OR T.ServiceIDs LIKE '%,#SegmentID#,%' OR T.ServiceIDs LIKE '%,#SegmentID#') 

を、変数SegmentIDが1つ以上の値であることを示す。実際にはSegmentIDに値が設定されていることを確認するCFIFステートメントの中にありました(これは既定のロジックが原因で常に発生していました)。

私は個人的には提案していますが、私はいつもあなたが0から多くのPKを別のテーブルのPKに関連した1つのテーブルから持つことを可能にするブリッジングテーブルと呼んでいます。

私はテーブル構造を変更できず、カスタムテーブルタイプと関数セットを使用して、テーブルから来ているかのようにSQLを介して値を扱うことができますが、カスタムテーブルタイプのソリューションはOracle固有のものでしたが、私の研究について。

0

リストを照会するのが難しい理由があります。データベースは、区切りリストで動作するように設計されていません。それらは、データの行(またはセット)に最も適しているように最適化されています。適切なテーブル構造を作成すると、クエリのパフォーマンスが向上し、SQLクエリがより簡単になります。 (技術的には可能ですが、Toddや他の人が示唆しているように、データベースを正規化することを真剣に考えなければなりません。)

Many-to-many関係は3つの表によって最もよく表現されます。さまざまな「サイズ」で「ウィジェット」を販売しているとします。、

ウィジェット(ユニークなウィジェット)

WidgetID | WidgetTitle 
1  | Widget 1 
2  | Widget 2 
.... 

サイズ(ユニークサイズ)

SizeID | SizeTitle 
7  | X-Small 
8  | Small 
9  | Medium 
10  | Large 
11  | X-Large 

は、次にジャンクションテーブルを作成します。メインのエンティティ表す2つのテーブルを作成します。それらの2つのエンティティ間の関係、すなわちどのウィジェットが利用可能であるかを格納するその構造により

WidgetSize(各ウィジェットのために使用可能なサイズ)

WidgetID | SizeID 
1  | 7   <== Widget 1 "X-Small" 
1  | 8   <== Widget 1 + "Small" 
2  | 7   <== Widget 2 + "X-Small" 
2  | 9   .... 
2  | 10 
2  | 11 
.... 

のサイズしたeは、簡単にサイズのリストのいずれか(またはすべて)を有するすべてのウィジェットを返すことができます。テストされていませんが、以下のようなSQLが動作するはずです。サイズのいずれかので利用可能な

  • 検索ウィジェット:<cfset listOfSizes = "7,9,11">

    SELECT w.WidgetID, w.WidgetTitle 
    FROM Widget w 
    WHERE EXISTS 
         ( SELECT 1 
          FROM WidgetSize ws 
          WHERE ws.WidgetID = w.WidgetID 
          AND ws.SizeID IN ( 
            <cfqueryparam value="#listOfSizeIds#" 
              cfsqltype="cf_sql_integer" list="true" > 
           ) 
         ) 
    
  • はすべてスリーサイズで利用可能なウィジェットを探す:<cfset listOfSizes = "7,9,11">

    SELECT w.WidgetID, w.WidgetTitle, COUNT(*) AS MatchCount 
        FROM  Widget w INNER JOIN WidgetSize ws ON ws.WidgetID = w.WidgetID 
        WHERE ws.SizeID IN ( 
            <cfqueryparam value="#listOfSizeIds#" 
              cfsqltype="cf_sql_integer" list="true" > 
          ) 
        GROUP BY w.WidgetID, w.WidgetTitle 
        HAVING MatchCount = 3 
    
関連する問題