【发布时间】:2020-09-23 16:36:06
【问题描述】:
我有 3 个表(关系多对多),我想选择只匹配所有选定类别的图像。
(下面的示例表)
过滤示例:
- (1) 获取图片并按类别过滤:'1' => 结果:61、62
- (2) 获取图像并按类别过滤:'1' AND '2' => 结果:61
- (1) 获取图片并按类别过滤:'2' => 结果:61、63、64li>
- (2) 获取图像并按类别过滤:'2' AND '3' => 结果:61、64li>
- (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