2016-06-19 5 views
1

私は、ユーザー検索の状態を格納するテーブルを持っています。それは次のようになります。条件がテーブルに格納されているmysqlの行を選択する方法は?

id | user_id | option | condition | value 
------------------------------------------ 
4 |  2 | price | >=  | 300000 
5 |  2 | price | <=  | 900000 
6 |  4 | status | =   | 1  
7 |  4 | type | =   | 1  
8 |  5 | price | >=  | 100000 
9 |  5 | price | <=  | 125000 
10 |  5 | status | =   | 2  
11 |  5 | type | >=  | 2  
13 |  6 | price | >=  | 200000 
14 |  7 | price | >=  | 500000 
18 |  8 | price | <=  | 600000 
------------------------------------------ 

は今、私はすべての400000price値は(ユーザーあたり)いずれかの条件範囲に合うuser_id、OR status試合1を取得する必要があります。

したがって、このクエリでは、結果は2,4,6,8である必要があります。

ご提案は大歓迎です!

UPD:http://sqlfiddle.com/#!9/ea73a4/1

+1

あなたは 'price_min、price_max'のような列を持つようにテーブルスキーマを変更することもできます。片面範囲の場合、非常に大きな正と負の境界を設定できます。 – Thilo

+0

ありがとうございます。はい、それはうまくいくかもしれませんが、私は大量のオプションが心配です。現在約20のオプションが保存されています。そして彼らはさらに成長するかもしれません。 – WarGasm

+0

sqlfiddleを投稿する – Strawberry

答えて

0

には、次の試してみてください;)

select distinct s.`user_id` 
from `search_state` s 
inner join (
    select `option`, `user_id`, max(`value` + 0) as maxV, min(`value` + 0) as minV, group_concat(`condition`) as `condition` 
    from `search_state` 
    where `user_id` = `user_id` 
    and `option` = `option` 
    and `option` = 'price' 
    group by `option`, `user_id` 
) t on s.`option` = 'status' and s.`value` = '1' 
or (
    s.`option` = 'price' and (
     s.`user_id` = t.`user_id` 
     and s.`option` = t.`option` and 
     case 
      when t.maxV = t.minV and find_in_set(',', t.`condition`) <> 0 
       then 400000 = t.`maxV` 
      when t.maxV = t.minV and find_in_set(',', t.`condition`) = 0 and t.`condition` = '>=' 
       then 400000 >= t.maxV 
      when t.maxV = t.minV and find_in_set(',', t.`condition`) = 0 and t.`condition` = '<=' 
       then 400000 <= t.maxV 
      when t.maxV <> t.minV then (400000 >= t.minV and 400000 <= t.maxV) 
     end 
    ) 
) 

SQLFiddle DEMO HERE

関連する問題