给出一个表定义:
class Aside extends Component {
render() {
return (
<Sidebar className={this.props.className}>
<List>
<Item>Pintrest 1</Item>
<Item>Pintrest 2</Item>
<Item>Pintrest 3</Item>
</List>
</Sidebar>
);
}
}
我想选择包含来自给定列表的通配符的所有标记的对象。类似的问题已被多次询问,并回答更简单的变体看起来或多或少像这样:
Objects:
obj_id | obj_name
-------|--------------
1 | object1
2 | object2
3 | object3
Tags:
tag_id | tag_name
-------|--------------
1 | code:python
2 | code:cpp
3 | color:green
4 | colorful
5 | image
objects_tags:
obj_id | tag_id
-------|---------
1 | 1
1 | 2
2 | 1
2 | 3
3 | 1
3 | 2
3 | 3
但是此解决方案不适用于通配符。是否有可能创建类似的查询,返回每个给定通配符查询返回至少1个标记的对象?检查SELECT obj_id,count(*) c FROM objects_tags
INNER JOIN objects USING(obj_id)
INNER JOIN tags USING(tag_id)
WHERE (name GLOB 'code*' OR name GLOB 'color*')
GROUP BY obj_id
HAVING (c==2)
是否不起作用,因为一个通配符标记可以返回多个结果,而另一个可能返回0仍然通过查询,即使它不应该。
我考虑过构建由客户端软件构建的动态查询,该客户端软件由N c>=2
s(每个标签一个)组成,因为可能不会有很多,但它听起来像是非常脏的解决方案,如果还有更多SQL方式然后我更喜欢使用它。
答案 0 :(得分:1)
SQLite支持WITH clause所以我会尝试先用它来确定所有标签,然后用这些标签以下面的方式查找对象。
示例(demo)是为PostGreSQL制作的,因为我无法在任何在线测试人员上运行SQLIte,但我相信你会将它轻松转换为SQLite:
此查询检索所有标记:
WITH tagss AS (
SELECT * FROM Tags
WHERE tag_name LIKE 'code:%' OR tag_name LIKE 'color:%'
)
SELECT * FROM tagss;
| tag_id | tag_name |
|--------|-------------|
| 1 | code:python |
| 2 | code:cpp |
| 3 | color:green |
并且最终查询以这种方式使用上面的子查询:
WITH tagss AS (
SELECT * FROM Tags
WHERE tag_name LIKE 'code:%' OR tag_name LIKE 'color:%'
)
SELECT obj_id,count(*) c
FROM objects_tags
INNER JOIN tagss USING(tag_id)
WHERE tag_name IN ( SELECT tag_name FROM tagss)
GROUP BY obj_id
HAVING count(*) >= (
SELECT count(*) FROM tagss
)
| obj_id | c |
|--------|---|
| 3 | 3 |