私は最近、複雑なSQLクエリに苦労しています。
私は次のテーブルを持っています:
[dbo].[User] ~ {ID,nickname}
[dbo].[Property] ~ {ID,title}
[dbo].[Property_Values] ~ [ID,propertyID,title}
[dbo].[Property_Values_User_Linkage] ~ {UserID,PropertyID,valueID}
これは基本的に、ユーザーが各プロパティの値を選択するプロジェクトです。各プロパティは、単一値または複数値にすることができます。たとえば、ユーザーはプロパティ{ID = 1、title = Hobbies}に複数の値を選択できますが、プロパティ{ID = 2、title=HairColor}には単一の値を選択する必要があります。
別のテーブルを使用する-[dbo]。[Search_Property_Values_User_Linkage]-{UserID、PropertyID、valueID}必要なプロパティを選択しており、一致するユーザーを見つけることを期待しています。ただし、HairColorなどの値(または複数値)を選択していない場合は、すべてのユーザーを取得する必要があります(HairColorでフィルター処理したくないため)。
これまでのところ簡単ですが、私が解決できないと思われる問題は、複数の値が先にあるか、ユーザー定義の値がない場合です。たとえば、HairColor =BrownとHobbiesIN(basketball、football)のすべてのユーザーが必要です。
いずれかの用語に一致するすべてのユーザー(および、フィルターを選択していないため、他のプロパティを持つユーザー)を取得できますが、条件に完全に一致するユーザーのみを取得することはできません。
コードを言葉にするために、次のようなすべてのユーザーが必要だとしましょう。
- 私が選択したすべてのプロパティ値に一致する
- EyesColorなどの他のプロパティがある場合もありますが、フィルタリング値を選択していないため、それらも取得される可能性があります。
- プロパティがまったく設定されていない可能性がありますが、このプロパティの値を選択していないため、有効です。
- 私が選択した1つのプロパティだけでなく、選択したすべてのプロパティをグループとして一致させます(バスケットボールが好きで、HairColorに「赤」が付いているユーザーは無効です!
選択されていない値をビット単位で「補完」する仮想テーブルを作成するソリューションに出くわしました。たとえば(実際のコードではありません):
DECLARE @isMatches bit
SET @isMatches=0
if [propertyIsChosen]=1
{
if [userInProperty]=1 SET @isMatches=1
}
else SET isMatches=1
基本的に、[Property] WITH [User]をCROSS-
JOINし、残りのテーブルをLEFT-OUTER-JOINして、選択に一致させます。
すべてのユーザーとそのプロパティへの一致を取得します。茶色の髪のユーザー、バスケットボール/サッカーが好きなユーザーはいますが、両方に一致するユーザー(そしてもちろん私が他の未定義のプロパティ)を持っているユーザーはいないので、これでは十分ではありません。
これは重いですが、問題を分析するためにこれまでに得たものです。
助けていただければ幸いです。10年前の数学の授業で何かが足りないと思います...
編集:db pic:http: //i51.tinypic.com/2n1cfwg.png