2016-08-05 3 views
2

현재 작업중인 응용 프로그램에는 사용자가 앨범을 만들고 이미지를 업로드 할 수있는 부분이 포함되어 있습니다. 응용 프로그램은 이미지의 여러 크기 조정을 작성하여 큰 버전이 사용자에게 제공되지 않도록합니다. 파일에 대한 모든 정보는GROUP BY가 유지해야하는 행을 지정하는 방법 및 접을 수 있어야합니다

  1. 앨범 테이블은 ID와 이름이 다음과 같은 구조의 데이터베이스에 저장됩니다
  2. 사진 테이블 사진의 목록을 가지고 있으며, 그들 각각은
  3. 에 속하는 어떤 앨범을 알고 photo_versions도 있습니다. 각 photo_versions는 Photo 테이블의 개체 ID를 저장합니다.

이 논리는 다음과 같은 스키마에 의해 표현된다 :

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에 의해 그룹에 필요한이 모든 테이블을 조인 시작 사진). 하나 명의 I에 가장 가까운 높이의 (그러나

+------+------+----+-----------+-------+------+-----------+-------+--------+ 
| 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) 

, 그것은 반드시 속성 행을 유지하지 않습니다

다음 표에 결과
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; 

이 : 그래서, 요청은로 변신 지정됨). photos_id로 그룹화하고 가장 가까운 높이의 것을 어떻게 선택합니까?

P. SQL 피들이 첨부 됨 - http://sqlfiddle.com/#!9/84f4f/1

+1

반환 할 행을 결정하는 요소는 무엇입니까? 쿼리에서 '높이'를 어디에 지정 했습니까? – sgeddes

+0

@sgeddes 그게 내 질문에 묻는 것입니다. –

답변

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을 높이로 검색 한 값으로 바꿀 수 있습니다.

관련 문제