2011-01-12 1 views
0

私はグループごとに格納されている連絡先のリストを取得する小さなプロジェクトに取り組んでいます。基本的に、データベースは、各グループがGroup.PrimaryとGroup.Secondaryとして記憶されているプラ​​イマリとセカンダリの連絡先を持つように設定されています。目的は、各グループのすべてのプライマリとセカンダリの連絡先を引き出し、並べ替え可能なテーブルに表示することです。MySQLクエリの列のような列

私はすべてのソート可能なテーブルを持っているが働いたが、私は小さな問題に遭遇してきました。各プライマリフィールドとセカンダリフィールドには、複数の連絡先をコンマで区切って指定することができます。プライマリが123256が含まれている場合たとえば、それは私がこのような形式にクエリを使用することを意図していたIDが123と256とのコンタクトの両方プルする必要があります:私はちょうどコンマ部分をスキップすることができるように

SELECT * 
    FROM Group G, 
     Contacts C 
WHERE G.Primary LIKE %C.ID% 
    OR G.Secondary LIKE %C.ID% 

を、しかし、私はこれのために動作するクエリを見つけることができないようです。

あなたに私の質問は、私はここで何かを見落としていますか?私にこれをさせる簡単なクエリはありますか?あるいは、私はグループと連絡先を別々に取得することをお勧めします。私は前者が読んだときに少し分かりやすいと思います。これは共有プロジェクトなのでプラスですが、それが不可能な場合は後者を行います。

このコードは簡略化されていますが、ポイントを取得します。

+0

データベース内に1対多の関係があります。 1つのグループには1つ以上の連絡先が関連付けられています。ほとんどの人は、groupidとcontact idの組み合わせを含む余分なテーブルを追加することでこれを解決します。このようにして、通常の結合を使用して、グループと関連付けられたすべての連絡先を取得できます。追加の利点は、毎回コンマ区切りの値を持つ文字列を '解析する'よりもずっと速いということです。 – Gerben

+0

悲しいことに、残念ながら、それは従来のデータベースであり、あまりにも多くのシステムが構造を変更するためにそれに依存しているので、そのまま維持する必要があります。私はここで解決策を試し、私は何が起こるか見る。 – shmeeps

答えて

3

私が正しく理解していれば、あなたはMySQL FIND_IN_SET functionを使用したい:

SELECT * 
    FROM Group G 
    JOIN Contacts C ON FIND_IN_SET(c.id, g.primary) 
        OR FIND_IN_SET(c.id, g.secondary) 

しかし、私は非常にあなたがテーブルを正規化をお勧めします - すべての可能性であれば、カンマ区切りのリストを格納しないでください。

+0

これはトリックでした、ありがとう! – shmeeps

0

私はあなたが別のテーブルにこれら2つのデータ値を分離して、あなたのリンクを行うにはJOIN Sを使用してオフに間違いなく良いだと思います。 idフィールドを文字列にキャストしてLIKEの比較を使用できるようにすると、多くのジャンクマッチが発生します。たとえば、あなたの主なidが1で、セカンダリが35である場合、その後、あなたは次のように一致するだろう(このリストは完全ではありません):

1: 1, 2: 35 
1: 35, 2: 1 
1: 10, 2: 135 
1: 431, 2: 3541 

など

私は何をしたいです代わりに行い、このようなものである:私は私が正しく質問を理解していればそれは、あなたが本当に探しているデータを取得すると思う

SELECT * 
FROM Group G 
LEFT JOIN Contacts c1 on g.primary = c1.id 
LEFT JOIN Contacts c2 on g.secondary = c2.id 
WHERE 
c1.id IS NOT NULL 
OR 
c2.id IS NOT NULL 

0

サタンはそれを非正規化し、複雑で遅いクエリの人生にあなたをdooming、自分のデータベースになっています。

データベースの構造を変更できますか?もしそれが生産されているなら、私はそうではないと思います。このレポートを実行する直前に、プライマリとセカンダリの連絡先の正規化されたテーブルを作成することを検討することをお勧めします。

あなたがそれを行うことができない場合、あなたは常に動作します文字列照合アルゴリズムをうまくする必要があります。あなたが提案した問題は、23(または3)の連絡先IDを検討する必要があることです.23、123、223、231などと一致します。その作業を行うには、比較している両方の文字列の先頭と末尾にカンマを追加してからLIKEを実行する必要があります。

あるいは、上記のPoniesで説明されている、まったく知らないFIND_IN_SET関数を使用することもできます。

+0

ここでは合唱団に説教しますが、FIND_IN_SETでも目的のマッチの逆転に合っています。これはまだ迷惑データです。私は正規化がここに行く方法だと完全に同意します。 –

関連する問題