1

一些背景:“图像”是一个“照片”的一部分,可能是零个或许多“画廊”的一部分。我的桌子:

“射击”表:

+----+--------------+
| id | name         |
+----+--------------+
|  1 | Test shoot   |
|  2 | Another test |
|  3 | Final test   |
+----+--------------+

“图像”表:

+----+-------------------+------------------+
| id | original_filename | storage_location |
+----+-------------------+------------------+
|  1 | test.jpg          | store/test.jpg   |
|  2 | test.jpg          | store/test.jpg   |
|  3 | test.jpg          | store/test.jpg   |
+----+-------------------+------------------+

'shoot_images' 表:

+----------+----------+
| shoot_id | image_id |
+----------+----------+
|        1 |        1 |
|        1 |        2 |
|        3 |        3 |
+----------+----------+

'gallery_images' 表:

+------------+----------+
| gallery_id | image_id |
+------------+----------+
|        1   |        1 |
|        1   |        2 |
|        2   |        3 |
|        3   |        1 |
|        4   |        1 |
+------------+----------+

我想回来,所以我可以说'对于这张照片,总共有 X 张图片,这些图片在 Y 画廊中精选:

+----+--------------+-------------+---------------+
| id | name         | image_count | gallery_count |
+----+--------------+-------------+---------------+
|  3 | Final test   |           1 |             1 |
|  2 | Another test |           0 |             0 |
|  1 | Test shoot   |           2 |             4 |
+----+--------------+-------------+---------------+

我目前正在尝试下面的 SQL,它似乎工作正常,但只返回一行。我无法弄清楚为什么会这样。奇怪的是,即使 'shoots' 为空,下面也会返回一行。

SELECT shoots.id,
       shoots.name,
       COUNT(DISTINCT shoot_images.image_id) AS image_count,
       COUNT(DISTINCT gallery_images.gallery_id) AS gallery_count
FROM shoots
LEFT JOIN shoot_images ON shoots.id=shoot_images.shoot_id
LEFT JOIN gallery_images ON shoot_images.image_id=gallery_images.image_id
ORDER BY shoots.id DESC

感谢您花时间看这个:)

4

2 回答 2

3

您缺少以下GROUP BY条款:

SELECT
     shoots.id,
     shoots.name,
     COUNT(DISTINCT shoot_images.image_id) AS image_count,
     COUNT(DISTINCT gallery_images.gallery_id) AS gallery_count
FROM shoots
LEFT JOIN shoot_images ON shoots.id=shoot_images.shoot_id
LEFT JOIN gallery_images ON shoot_images.image_id=gallery_images.image_id
GROUP BY 1, 2 -- Added this line
ORDER BY shoots.id DESC

注意:SQL 标准允许GROUP BY给定列名或列号,因此在这种情况下GROUP BY 1, 2等价于。GROUP BY shoots.id, shoots.name有很多人认为这种“糟糕的编码实践”并主张始终使用列名,但我发现它使代码更具可读性和可维护性,并且在该站点上的许多用户出生之前,我就一直在编写 SQL,并且使用这种语法永远不会给我带来问题。


仅供参考,您之前获得一行而不是错误的原因是,在 mysql 中,与我所知道的任何其他数据库不同,您可以group by在使用聚合函数时省略该子句。在这种情况下,mysql 不会抛出语法异常,而是为非聚合列的每个唯一组合返回第一行。

虽然起初这对 SQL 纯粹主义者来说似乎很可恶,但它可以非常方便!

于 2012-06-17T14:18:11.787 回答
1

您应该查看 MySQL 函数组。

于 2012-06-17T14:15:27.163 回答