人気ブログランキング | 話題のタグを見る

SQLiteで複数のColumnsに対して同じ条件を適用する

今作ってる「サモンズ図鑑」の検索機能の実装で躓いた出来事
キャラ1体に対して特殊能力の枠が3つあるんだけど、
これを条件としたフィルタがなかなか上手くいかなかった

特殊1・特殊2・特殊3というフィールドに対して、それぞれ対応した値(能力)が付与される
具体例を挙げると
飛行→1
全体化→2
ハートアップ→3
防御アップLv.1→4・・・
といった具合になる

例えば進化後のゴーレムは全体化と防御アップLv.1を持ってるので
データとしては
特殊1→2
特殊2→4
特殊3→無し
という持ち方になる

でもこのままだと特殊1が防御アップLv.1で特殊2が全体化のデータはヒットしない
あくまで特殊1が全体化(=2)、特殊2が防御アップLv.1(=4)でないといけない

これを回避するためにSQLをどう構築すればいいのか
日本語的には「特殊1~3のどこかに2と4が入ったデータを抽出」したいわけね
とりあえずそれっぽく書いてみると下記のようになる

SELECT * FROM monster
WHERE Ability1 IN ( 2,4 )
OR Ability2 IN ( 2,4 )
OR Ability3 IN ( 2,4 )


これを実行すると騎士とかカーバンクルもヒットしてしまった
上記のSQLは厳密に審査すると「特殊1~3のどこかに2か4があるデータ」になってるからだ
全体化もしくは防御アップのどちらかを持ってるキャラまでヒットしてしまう
接続語をANDに変更すると今度は特殊3に2か4を持ってないといけないことになる

紆余曲折を経て以下のリクエストで解決した

SELECT * FROM monster
WHERE 2 IN ( Ability1, Ability2 ,Ability3 )
OR 4 IN ( Ability1, Ability2 ,Ability3 )


フィールドに値があるかを審査するのではなく
値がフィールドにあるかを審査している
これで必要なデータを個別に各フィールドに対してバリデーションが可能になった

こういう書き方があるんだな~と我ながら感心したので備忘録として
by onigirism | 2016-06-10 12:48 | Comments(0)
<< XAMLデザインビューのエラー... VisualStudioでAn... >>