SQL: 在不同 table 中查找符合条件的条目
SQL: Find entries with matching criteria in different table
我有两个 table,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 中表达的查询是:
Give me all Event
(all columns in the table) that have associated tags with EventTag.type="foo" and EventTag.value="bar"
.
这对于 one 标记条件来说很容易(例如,使用连接和 where,如回答 here),但我该如何处理这种情况两个或更多标准?所以:给我关联标签 "foo" 等于 "bar" 和(!)事件标签 "qux" 等于 "quux" 的事件?我想加入标签 table 'n' 次,但我不确定这是否是个好主意。
Select id from EVENT ev
INNER JOIN EVENT_TAG et
ON ev.id = et.event_ID
WHERE et.type = 'foo'
AND et.value = 'bar'
显然,您可以在括号中添加任何您想要的内容,以查找您想要的任何类型。
对多个 case/criteria 使用 Or 操作数
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 字符串分配给 Query 并为其设置参数。
解决这个问题最好的办法就是不使用EAV数据库模型(Entity-Attribute-Value)。您 运行 只是这个反模式的众多问题中的第一个。如果您选择不重新设计,在 "EAV model" 上快速 Google 搜索应该会发现一些其他的问题。通常你的 Event
table 应该有一列 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
)
如果您将各种 type/value 对放入临时 table 或作为 CTE,那么您可以 JOIN
到那个,而不是列出您想要的所有对。不过,该语法将取决于您的 RDBMS。
我有两个 table,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 中表达的查询是:
Give me all
Event
(all columns in the table) that have associated tags withEventTag.type="foo" and EventTag.value="bar"
.
这对于 one 标记条件来说很容易(例如,使用连接和 where,如回答 here),但我该如何处理这种情况两个或更多标准?所以:给我关联标签 "foo" 等于 "bar" 和(!)事件标签 "qux" 等于 "quux" 的事件?我想加入标签 table 'n' 次,但我不确定这是否是个好主意。
Select id from EVENT ev
INNER JOIN EVENT_TAG et
ON ev.id = et.event_ID
WHERE et.type = 'foo'
AND et.value = 'bar'
显然,您可以在括号中添加任何您想要的内容,以查找您想要的任何类型。
对多个 case/criteria 使用 Or 操作数
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 字符串分配给 Query 并为其设置参数。
解决这个问题最好的办法就是不使用EAV数据库模型(Entity-Attribute-Value)。您 运行 只是这个反模式的众多问题中的第一个。如果您选择不重新设计,在 "EAV model" 上快速 Google 搜索应该会发现一些其他的问题。通常你的 Event
table 应该有一列 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
)
如果您将各种 type/value 对放入临时 table 或作为 CTE,那么您可以 JOIN
到那个,而不是列出您想要的所有对。不过,该语法将取决于您的 RDBMS。