繁体   English   中英

如何在多个联接行需要包含内容的地方执行SQL JOIN

[英]How to do a SQL JOIN where multiple joined rows need to contain things

当我网站上的某人搜索具有多个标签的图像时,我需要查询并找到所有具有搜索标签的图像,但似乎无法弄清楚该查询。

我有一个Images表。

Images表与Posts_Images有关系。

Posts_Images将与Posts表相关。

PostsPosts_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都具有我需要的所有值。

期望的结果将是具有匹配ComicILIKE '%Fallout%'标签的任何Post

您似乎想要这样的东西:

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%是否确实正是您想要多次比赛的结果。

除了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()
   $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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM