当我网站上的某人搜索具有多个标签的图像时,我需要查询并找到所有具有搜索标签的图像,但似乎无法弄清楚该查询。
我有一个Images
表。
Images
表与Posts_Images
有关系。
Posts_Images
与Posts
表有关系。
Posts
与Posts_Tags
表有关系。
Posts_Tags
表将具有与Tags
表的关系。
我到目前为止的查询:
SELECT "images".* FROM "images"
INNER JOIN "posts_images" ON posts_images.image_id = images.id
INNER JOIN "posts" ON posts.id = posts_images.post_id AND posts.state IS NULL
INNER JOIN "posts_tags" ON posts_tags.post_id = posts.id
INNER JOIN "tags" ON posts_tags.tag_id = tags.id
WHERE (("images"."order"=0) AND ("images"."has_processed"=TRUE)) AND (LOWER(tags.tag)='comic') AND ("tags"."tag" ILIKE '%Fallout%') ORDER BY "date_uploaded" DESC LIMIT 30
没有任何结果,它正在检查tags
是否等于两个值,但是我想查看联接的tags
中是否有我需要的所有值。
期望的结果将是任何具有与Post
和Comic
匹配的标签的ILIKE '%Fallout%'
答案 0 :(得分:2)
您似乎想要这样的东西:
SELECT i.*
FROM images JOIN
posts_images pi
ON pi.image_id = i.id JOIN
posts p
ON p.id = pi.post_id AND p.state IS NULL JOIN
posts_tags pt
ON pt.post_id = p.id JOIN
tags t
ON pt.tag_id = t.id
WHERE i."order" = 0 AND
i.has_processed AND
(LOWER(t.tag) = 'comic') OR
(t.tag ILIKE '%Fallout%')
GROUP BY i.id
HAVING COUNT(DISTINCT tag) >= 2
ORDER BY date_uploaded DESC
LIMIT 30;
逻辑在HAVING
子句中。我不确定100%是否正是您想要进行多次比赛的方式。
答案 1 :(得分:2)
除了gordon-linoff的回复-可以使用ActiveQuery描述查询:
Images::find()
->alias('i')
->joinWith([
'postsImages pi',
'postsImages.posts p',
'postsImages.posts.tags t'
])
->where([
'p.state' => null,
'i.order' => 0,
'i.has_processed' => true,
])
->andWhere(
'or'
'LOWER(t.tag) = "comic"',
['like', 't.tag', 'Fallout']
])
->groupBy('id')
->having('COUNT(DISTINCT tag) >= 2')
->orderBy('date_uploaded DESC')
->limit(30)
->all()
答案 2 :(得分:1)
$images = Images::find()
->innerJoin('posts_images', 'posts_images.image_id = images.id')
->innerJoin('posts', 'posts.id = posts_images.post_id AND posts.state IS NULL')
->where(['images.order' => 0, 'images.has_processed' => true]);
if (!is_null($query)) {
$tags = explode(',', $query);
$images = $images
->innerJoin('posts_tags', 'posts_tags.post_id = posts.id')
->innerJoin('tags', 'posts_tags.tag_id = tags.id');
$tagsQuery = ['OR'];
foreach ($tags as $tag) {
$tag = trim(htmlentities($tag));
if (strtolower($tag) == 'comic') {
$tagsQuery[] = ['tags.tag' => $tag];
} else {
$tagsQuery[] = [
'ILIKE',
'tags.tag', $tag
];
}
}
if (!empty($tagsQuery)) {
$images = $images->andWhere($tagsQuery)
->having('COUNT(DISTINCT tags.tag) >= ' . sizeof($tags));
}
}
$images = $images
->groupBy('images.id')
->orderBy(['date_uploaded' => SORT_DESC])
->offset($offset)
->limit($count);
return $images->all();