我有两张桌子,Event和EventTag
CREATE TABLE event (
id INT PRIMARY KEY,
content TEXT
)
CREATE TABLE event_tag (
event_id INT,
type VARCHAR(255),
value VARCHAR(255)
)每个事件都有零或多个标记。我想用SQL表示的查询是:
给我所有与
Event相关联的EventTag.type="foo" and EventTag.value="bar"(表中的所有列)。
对于一个标记条件(例如,使用一个连接和一个where,如应答的here),这很容易,但是如何处理两个或多个条件的情况呢?所以:给我一个关联标签"foo“等于"bar”和(!)的事件。事件标记"qux“等于"quux"?我想加入标签表的时间,但我不确定这是否一个好主意。
发布于 2016-07-05 13:30:41
解决这个问题的最好方法是不使用EAV数据库模型(实体-属性值)。你在这个反模式中遇到了许多问题中的第一个。在Google上快速搜索"EAV模型“,如果你选择不重新设计的话,你会发现其他一些问题。通常,您的Event表应该有一列用于foo,一列用于qux。
如果坚持(或被迫)走上这条道路,您可以使用一个可能的解决方案:
SELECT id, content
FROM Event
WHERE id IN
(
SELECT
E.id
FROM
Event E
INNER JOIN Event_Tag T ON
T.event_id = E.id AND
(
(T.type = 'foo' AND T.value = 'bar') OR
(T.type = 'qux' AND T.value = 'quux')
)
GROUP BY
E.id
HAVING
COUNT(*) = 2
)如果将各种类型/值对放入临时表或作为CTE,则可以对其进行JOIN处理,而不是列出所需的所有对。不过,这种语法将取决于您的RDBMS。
发布于 2016-07-05 13:21:19
Select id from EVENT ev INNER JOIN EVENT_TAG et ON ev.id = et.event_ID WHERE et.type = 'foo' AND et.value = 'bar'
显然,您可以将任何想要的东西放在括号之间,以找到您想要的类型。
发布于 2016-07-05 13:29:46
对多个情况/标准使用或操作数
SELECT * FROM Event e join Event_tag on e.eventId = et.eventtagid where ((EventTag.type="foo" and EventTag.value="bar") or (EventTag.type="po" and EventTag.value="yo"))如果值是动态的,则根据编程语言(接口为SQL ),可以编写查询。
例如,在java中,我可以使用
SELECT * FROM Event e join Event_tag et on e.eventid = et.eventtagid where (EventTag.type=? and EventTag.value=?)其中,我分配上面的SQL字符串来查询和设置它的参数。
https://stackoverflow.com/questions/38204475
复制相似问题