0

Properties(pid、uid、pname、pvalue)というテーブルがあります 。pid 列は自動生成されます。各 uid (ユーザー ID) は、pname と pvalue に複数の名前と値のペアを格納できます。

入力として、複雑なブール式を形成する pname と pvalue の名前と値のペアが複数あります。

例: 1 つの名前と値のペアから始めましょう。「favorite_color」が「red」であるすべての uid を取得したいとします。

私はSQLクエリを書きました:

SELECT * 
  FROM properties 
 WHERE ((pname = 'favorite_color') and (pvalue = 'red'))

'favorite_color' が 'red' または 'blue' であり、'favorite_drink' が 'juice' または ''milk' であり、'favorite_ Hobby' が 'music' であるすべての uid をフェッチするようなものを取得する必要がある場合、クエリはすぐに複雑になります。または「芸術」など。

私はSQLクエリを書きました:

SELECT * 
  FROM properties 
 WHERE (((pname = 'favorite_color') and (pvalue = 'red')) 
    OR ((pname = 'favorite_color') and (pvalue = 'blue'))) 
   AND (((pname = 'favorite_drink') and (pvalue = 'juice')) 
    OR ((pname = 'favorite_drink') and (pvalue = 'milk'))) 
   AND (((pname = 'favorite_hobby') and (pvalue = 'music')) 
    OR ((pname = 'favorite_hobby') and (pvalue = 'art')))

式は正しくなりましたが、残念ながら各行で評価が行われるため失敗します。where 句にさらに名前と値のペアを追加したい場合はどうすればよいでしょうか?

質問:

  1. これを記述してSQLクエリを実行することは可能ですか?

  2. 私が持っていたもう 1 つのアイデアは、各ユーザーのすべての pname と pvalue のペアを取得し、式言語を使用して動的な式を作成し、入力された名前の値 paris を評価することでした。私はApacheのJEXLを念頭に置いています。

4

2 に答える 2

2

ANDを実行するには、and-ed条件と同じ数の自己結合を実行する必要があります。

SELECT *
FROM Properties p1, Properties p2, Properties p3
WHERE p1.uid = p2.uid AND p1.uid = p3.uid
AND (p1.pname = 'favorite_color' AND p1.pvalue IN ('red', 'blue'))
AND (p2.pname = 'favorite_drink' AND p2.pvalue IN ('juice', 'milk'))
AND (p3.pname = 'favorite_hobby' AND p2.pvalue IN ('music', 'art'))

編集:

もう1つの可能性は、データを非正規化してから、FIND_IN_SET()またはを使用することRLIKEです。

SELECT uid, group_concat(concat(pname, '=', pvalue)) props
FROM Properties
GROUP BY uid
HAVING props RLIKE 'favorite_color=(red|blue)'
AND props RLIKE 'favorite_drink=(juice|milk)'
AND props RLIKE 'favorite_hobby=(music|art)'
于 2012-08-26T03:22:58.543 に答える
0
SELECT p1.*,p2.pname,p2.pvalue,p3.pname,p3.pvalue
FROM (
       (Select * 
        from Properties  
        where (pname = 'favorite_color' AND pvalue IN ('red', 'blue')) p1, 
       (Select * 
        from Properties  
        where (pname = 'favorite_drink' AND pvalue IN ('juice','milk')) p2, 
       (Select * 
        from Properties  
        where (pname = 'favorite_hobby' AND pvalue IN ('music', 'art')) p3, 
     )
WHERE p1.uid = p2.uid AND p1.uid = p3.uid
于 2012-08-26T04:30:17.070 に答える