【问题标题】:SQL/Doctrine - Filtering results with AND (many to many)SQL/Doctrine - 使用 AND(多对多)过滤结果
【发布时间】:2020-09-23 16:36:06
【问题描述】:

我有 3 个表(关系多对多),我想选择只匹配所有选定类别的图像。

(下面的示例表)

过滤示例

  • (1) 获取图片并按类别过滤:'1' => 结果:61、62
  • (2) 获取图像并按类别过滤:'1' AND '2' => 结果:61
  • (1) 获取图片并按类别过滤:'2' => 结果:61、63、64​​li>
  • (2) 获取图像并按类别过滤:'2' AND '3' => 结果:61、64​​li>
  • (3) 获取图像并按类别过滤:'1' AND '2' AND '3' => 结果:61

结论:

我想在添加新类别进行过滤时缩小搜索结果的范围。 有没有人遇到过这样的问题?

我试图通过 WHERE, JOINs clausules 找到解决方案,但没有任何工作正常。 最接近解决方案的是创建一个附加列,其中包含一个包含类别 ID 的数组。

SELECT
    images.id,
    ARRAY(SELECT images_categories.category_id FROM images_categories where images_categories.image_id = images.id order by images_categories.category_id)
FROM
    images
ORDER BY images.id

在 WHERE 子句中 SQL“看不到”类别列

WHERE
    (1) in categories

图片

+----+------------------------+
| id | Some another fields... |
+----+------------------------+
| 61 | ...                    |
+----+------------------------+
| 62 | ...                    |
+----+------------------------+
| 63 | ...                    |
+----+------------------------+
| 64 | ...                    |
+----+------------------------+

类别

+----+------+
| id | name |
+----+------+
| 1  | ...  |
+----+------+
| 2  | ...  |
+----+------+
| 3  | ...  |
+----+------+

images_categories(有关系的表)

+----------+-------------+
| image_id | category_id |
+----------+-------------+
| 61       | 1           |
+----------+-------------+
| 61       | 2           |
+----------+-------------+
| 61       | 3           |
+----------+-------------+
| 62       | 1           |
+----------+-------------+
| 63       | 2           |
+----------+-------------+
| 64       | 2           |
+----------+-------------+
| 64       | 3           |
+----------+-------------+

解决方案(SQL + Symfony 原则):

经过几天的寻找解决方案,我的朋友给我发了一个关于此事的新观点。您可以在下面找到 WORKING SQL 解决方案:

SELECT images.id
FROM images
LEFT JOIN images_categories
    ON image.id = images_categories.image_id
LEFT JOIN categories
    ON categories.id = images_categories.category_id
WHERE categories.id IN (1, 2)
GROUP BY images.id
HAVING COUNT(DISTINCT categories.id) = 2;

说明:

WHERE categories.id IN (1, 2) // <= Array of categories ids
HAVING COUNT(DISTINCT categories.id) = 2; // <= Count of categories array

(Symfony)学说中的解决方案:

        $qb = $this->getEntityManager()->createQueryBuilder();

        $qb
            ->select('image')
            ->from($this->_entityName, 'image')
            ->leftJoin('image.category', 'category');

        // Implemented solution:
        $qb
            ->andWhere('category.id IN (:categoriesIds)')
            ->setParameter('categoriesIds', $categoriesIds)
            ->groupBy('image.id')
            ->having('COUNT(DISTINCT category.id) = :categoriesCount')
            ->setParameter('categoriesCount', count($categoriesIds));

        $qb->getQuery()->getResult();

【问题讨论】:

    标签: sql doctrine subquery filtering where-clause


    【解决方案1】:

    你可以用这个:

    select I.id
    from images as I
    where I.id in ( select image_id from images_categories group by image_id having 
    COUNT(*) = ( select COUNT(*) as c from
    categories ))
    

    【讨论】:

      猜你喜欢
      • 2012-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-19
      相关资源
      最近更新 更多