我正在处理的应用程序包含用户可以创建相册并将图像上传到其中的部分。应用程序会创建几个图像调整大小,以便不向用户提供大版本。有关文件的所有信息都以以下结构存储在数据库中
此逻辑由以下架构表示:
CREATE TABLE albums(`id` int, `name` varchar(255));
INSERT INTO albums (id, name) VALUES
(1, "one"),
(2, "two"),
(3, "three");
CREATE TABLE photos(`id` int, `albums_id` int, `title` varchar(255));
INSERT INTO photos (id, albums_id, title) VALUES
(1, 1, "a"),
(2, 1, "b"),
(3, 1, "c");
CREATE TABLE photos_versions(`id` int, `photos_id` int, `width` int, `height` int);
INSERT INTO photos_versions (photos_id, width, height) VALUES
(1, 1000, 800),(1, 800, 600), (1, 600, 400),
(2, 1000, 800), (2, 800, 600), (2, 600, 400),
(3, 1000, 800), (3, 800, 600), (3, 600, 400);
用户界面能够请求特定的高度,我正在处理的后端应该返回数据库中最接近的高度。我正在按照要求去做。它从加入所有这些表开始:
SELECT *
FROM albums a
INNER JOIN photos p ON p.albums_id = a.id
INNER JOIN photos_versions pv ON pv.photos_id = p.id;
结果如下表所示:
+------+------+----+-----------+-------+------+-----------+-------+--------+
| id | name | id | albums_id | title | id | photos_id | width | height |
+------+------+----+-----------+-------+------+-----------+-------+--------+
| 1 | one | 1 | 1 | a | NULL | 1 | 1000 | 800 |
| 1 | one | 1 | 1 | a | NULL | 1 | 800 | 600 |
| 1 | one | 1 | 1 | a | NULL | 1 | 600 | 400 |
| 1 | one | 2 | 1 | b | NULL | 2 | 1000 | 800 |
| 1 | one | 2 | 1 | b | NULL | 2 | 800 | 600 |
| 1 | one | 2 | 1 | b | NULL | 2 | 600 | 400 |
| 1 | one | 3 | 1 | c | NULL | 3 | 1000 | 800 |
| 1 | one | 3 | 1 | c | NULL | 3 | 800 | 600 |
| 1 | one | 3 | 1 | c | NULL | 3 | 600 | 400 |
+------+------+----+-----------+-------+------+-----------+-------+--------+
9 rows in set (0.00 sec)
现在,我们需要按照photos_id进行分组(因为我们希望得到最近的给定照片版本)。所以,请求变成了:
SELECT *
FROM albums a
INNER JOIN photos p ON p.albums_id = a.id
INNER JOIN photos_versions pv ON pv.photos_id = p.id
GROUP BY photos_id;
结果如下表所示:
+------+------+----+-----------+-------+------+-----------+-------+--------+
| id | name | id | albums_id | title | id | photos_id | width | height |
+------+------+----+-----------+-------+------+-----------+-------+--------+
| 1 | one | 1 | 1 | a | NULL | 1 | 1000 | 800 |
| 1 | one | 2 | 1 | b | NULL | 2 | 1000 | 800 |
| 1 | one | 3 | 1 | c | NULL | 3 | 1000 | 800 |
+------+------+------+-----------+-------+------+-----------+-------+--------+
3 rows in set (0.00 sec)
但是,它不一定保留具有属性的行(具有最接近我指定的高度的行)。如何分组photos_id并选择距离最近的那个?
P.S。附上了SQL小提琴 - http://sqlfiddle.com/#!9/84f4f/1
答案 0 :(得分:1)
此处的一种方法是在查询中添加其他联接,这将限制为每个照片ID组具有最接近高度的照片。
SELECT a.*, p.*, pv1.*
FROM albums a
INNER JOIN photos p
ON p.albums_id = a.id
INNER JOIN photos_versions pv1
ON pv1.photos_id = p.id
INNER JOIN
(
SELECT photos_id, MIN(ABS(height - SOME_HEIGHT)) AS diff
FROM photos_versions
GROUP BY photos_id
) pv2
ON pv1.photos_id = pv2.photos_id AND
MIN(ABS(pv1.height - SOME_HEIGHT)) = pv2.diff
您可以将SOME_HEIGHT
替换为您从搜索高度获得的任何值。