2016-12-02 5 views
5

次は、顧客がライブラリで読むさまざまな種類の書籍のリストです。値は、bookTypeという列に2の累乗で格納されます。論理演算を使用してデータのリストをフェッチするMySQLクエリ

List of customer reading books

私は論理的な運用のクエリを使用して、データベースから only Novel Or only Fairytale Or only BedTime Or both Novel + Fairytale を読ん者の組み合わせで本のリストを取得する必要があります。

以下の組み合わせのためのリストを取得:(1とDBに格納されている)だけ小説1 + 2 = 3として、DBに格納された両方の新規でおとぎ話を(読み出し

  • 人を読み出し

    • 人)読み出し
    • 人すべての3つ、すなわち{新規+おとぎ話+ベッドタイム} 1 + 2 + 4 = 7)

    としてDBに格納されている(これらの数をdに格納されています(図中の赤でマークされた。)ブックタイプと呼ばれる列内のatabase

    私は例からMySQLのクエリ

    を使用して上記のリストを取得するにはどうすればよい、私は(小説の読者のようなユーザーを取得する必要があります1,3 、5,7)。

  • +1

    私は、列挙型と集合、または接合テーブルを調べることから始めます。 MySQLには、このような情報を格納する方がはるかに優れています。 –

    答えて

    1

    この質問の中心は10進数から2進数への変換であり、mysqlはちょうどCONV(num、from_base、to_base)を実行する関数を持っています。 この場合、from_base進数は10とto_baseだろうが、2 だろう私はこのUDFは

    +----+----------+---------------------------+ 
    | id | username | book_type(id)    | 
    +----+----------+---------------------------+ 
    | 1 | John  | novel,     | 
    | 2 | Jane  | fairy Tale,    | 
    | 3 | Ali  | novel,fairy Tale,   | 
    | 6 | Bruce | fairy Tale,bedtime,  | 
    | 7 | Martha | novel,fairy Tale,bedtime, | 
    +----+----------+---------------------------+ 
    5 rows in set (0.00 sec) 
    

    drop function if exists book_type; 
    delimiter // 
    
    CREATE DEFINER=`root`@`localhost` FUNCTION `book_type`(
        `indec` int 
    ) 
    RETURNS varchar(255) CHARSET latin1 
    LANGUAGE SQL 
    NOT DETERMINISTIC 
    CONTAINS SQL 
    SQL SECURITY DEFINER 
    COMMENT '' 
    begin 
    declare tempstring varchar(100); 
    declare outstring varchar(100); 
    declare book_types varchar(100); 
    declare bin_position int; 
    declare str_length int; 
    declare checkit int; 
    set tempstring = reverse(lpad(conv(indec,10,2),4,0)); 
    set str_length = length(tempstring); 
    set checkit = 0; 
    set bin_position = 0; 
    set book_types = ''; 
    looper: while bin_position < str_length do 
         set bin_position = bin_position + 1; 
         set outstring = substr(tempstring,bin_position,1); 
    
    
         if outstring = 1 then 
          set book_types = concat(book_types,(select trim(type) from t where id = bin_position),','); 
         end if; 
    end while; 
    
    set outstring = book_types; 
    
    return outstring; 
    end // 
    delimiter ; 
    

    結果

    MariaDB [sandbox]> select id,username 
        -> from users 
        -> where id < 8; 
    +----+----------+ 
    | id | username | 
    +----+----------+ 
    | 1 | John  | 
    | 2 | Jane  | 
    | 3 | Ali  | 
    | 6 | Bruce | 
    | 7 | Martha | 
    +----+----------+ 
    5 rows in set (0.00 sec) 
    
    MariaDB [sandbox]> select * from t; 
    +------+------------+ 
    | id | type  | 
    +------+------------+ 
    | 1 | novel  | 
    | 2 | fairy Tale | 
    | 3 | bedtime | 
    +------+------------+ 
    3 rows in set (0.00 sec) 
    

    与えUDF でこれをラップしますUDF内のループがバイナリ文字列を辿ることに注意してください。また、1の位置はルックアップテーブル内のIDに関連しています。 エラーをコードしてきちんと整理してください。

    +0

    例から、私は小説の読者(1,3,7)のようなセグメントを取り出す必要があります。これが私にどのように役立つのか説明できますか? – r123

    +0

    selectのwhere節でfind_in_set( 'novel'、book_type(u.id))を使用できます。 –

    +0

    @ruby最新のコメントを見ましたか? –

    関連する問題