jos*_*mes 4 mysql sql entity-attribute-value
我有2个相关的表:
messages
--------
mid subject
--- -----------------
1 Hello world
2 Bye world
3 The third message
4 Last one
properties
----------
pid mid name value
--- --- ---------------- -----------
1 1 read false
2 1 importance high
3 2 read false
4 2 importance low
5 3 read true
6 3 importance low
7 4 read false
8 4 importance high
Run Code Online (Sandbox Code Playgroud)
我需要从messages使用properties桌面上的标准中获益.例如:如果我有一个像return unread (read=false) high prio (importance=high) messages它应该返回的标准
mid subject
--- -----------------
1 Hello world
4 Last one
Run Code Online (Sandbox Code Playgroud)
我怎么能用SELECT子句(MySQL方言)得到它?
在SQL中,WHERE子句中的任何表达式一次只能引用一行.因此,您需要某种方法将属性表中的多行添加到一行结果中.你用自联接做到这一点:
SELECT ...
FROM messages AS m
JOIN properties AS pRead
ON m.mid = pRead.mid AND pRead.name = 'read'
JOIN properties AS pImportance
ON m.mid = pImportance.mid AND pImportance.name = 'importance'
WHERE pRead.value = 'false' AND pImportance.value = 'high';
Run Code Online (Sandbox Code Playgroud)
这表明使用EAV 反模式有多么尴尬.与使用常规属性进行比较,其中一个属性属于一列:
SELECT ...
FROM messages AS m
WHERE m.read = 'false' AND m.importance = 'high';
Run Code Online (Sandbox Code Playgroud)
顺便说一句,@ Abe Miessler和@Thomas的答案比你想要的更多.它们匹配所有中间值,其中read = false或者important = high.您需要将这些属性与AND的等效项组合在一起.
我相信下面的查询将有效.
更新: @Gratzy是对的,这个查询不起作用,看看我建议的结构变化.
SELECT DISTINCT m.id as mid, m.subject
FROM message as m
INNER JOIN properties as p
ON m.mid = p.mid
where (p.name = 'read' and p.value = 'false') or (p.name = 'importance' AND p.value = 'high')
Run Code Online (Sandbox Code Playgroud)
你的属性表的结构似乎有点偏离我...
是否可以像这样构造表:
messages
--------
mid subject Read Importance
--- ----------------- --------- ------------
1 Hello world false 3
2 Bye world false 1
3 The third message true 1
4 Last one false 3
importance
----------
iid importanceName
--- --------------
1 low
2 medium
3 high
Run Code Online (Sandbox Code Playgroud)
并使用此查询:
SELECT m.id as mid, m.subject
FROM message as m
where m.read = false AND m.importance = 3
Run Code Online (Sandbox Code Playgroud)