Выбрать последнюю строку из нескольких таблиц

У меня есть этот запрос с несколькими таблицами, и я получил следующий результат. Затем я хочу сгруппировать по t.id. Я знаю, что могу просто использовать группу по t.id, но как я могу выбрать последнюю строку t.id, которая является URL-адресом tw5.jpg и created_time 10000004

SELECT p.url,t.name,t.num_photo,t.id
FROM photos AS p
LEFT JOIN tag_maps AS tm ON p.id = tm.photo_id
LEFT JOIN tags AS t ON t.id = tm.tag_id

url                       created_time    name      num_photo  id
assets/img/tags/tw1.jpg   1000001         my house  1           1
assets/img/tags/tw2.jpg   1000002         dog       1           2
assets/img/tags/tw3.jpg   1000003         taiwan    2           3
assets/img/tags/tw5.jpg   1000004         taiwan    2           3

Это то, что я получаю при использовании группы по t.id

url                       created_time    name      num_photo  id
assets/img/tags/tw1.jpg   1000001         my house  1           1
assets/img/tags/tw2.jpg   1000002         dog       1           2
assets/img/tags/tw3.jpg   1000003         taiwan    2           3

И это то, что я хочу

url                       created_time    name      num_photo  id
assets/img/tags/tw1.jpg   1000001         my house  1           1
assets/img/tags/tw2.jpg   1000002         dog       1           2
assets/img/tags/tw5.jpg   1000004         taiwan    2           3

ОТРЕДАКТИРОВАНО

Фотографии стол

id    url                      created_time
1     assets/img/tags/tw1.jpg  1000001
2     assets/img/tags/tw2.jpg  1000002
3     assets/img/tags/tw3.jpg  1000003
4     assets/img/tags/tw5.jpg  1000004

Таблица тегов

id name     num_photo
1  my house 1
2  dog      1
3  taiwan   2

Tag_maps

id   tag_id   photo_id
1    1        1
2    2        2
3    3        3
4    3        4

person vzhen    schedule 14.01.2013    source источник


Ответы (1)


Редактировать № 2: не видя выборки данных из каждой таблицы или структур таблиц, я предполагаю, что будет работать следующее:

SELECT p.url,
  created_time,
  t.name,
  t.num_photo,
  t.id
FROM photos p
LEFT JOIN tag_maps AS tm 
    ON p.id = tm.photo_id
LEFT JOIN tags AS t 
    ON t.id = tm.tag_id
INNER JOIN
(
  select max(created_time) MaxDate, t.id
  FROM photos p
  LEFT JOIN tag_maps AS tm 
      ON p.id = tm.photo_id
  LEFT JOIN tags AS t 
      ON t.id = tm.tag_id
  group by t.id
) d
  on p.created_time = d.MaxDate
  and t.id = d.id;

См. SQL Fiddle с демонстрацией.

Или другой способ написать это с помощью подзапроса, который возвращает max(photo_id) на tag_Id из таблицы tag_maps и использует этот результат в объединении:

SELECT p.url,
  created_time,
  t.name,
  t.num_photo,
  t.id
FROM photos p
INNER JOIN
(
  select max(photo_id) photo_id, tag_id
  from tag_maps
  group by tag_id
) AS tm 
    ON p.id = tm.photo_id
LEFT JOIN tags AS t 
    ON t.id = tm.tag_id

См. SQL Fiddle с демонстрацией.

Результат:

|                     URL | CREATED_TIME |     NAME | NUM_PHOTO | ID |
----------------------------------------------------------------------
| assets/img/tags/tw1.jpg |      1000001 | my house |         1 |  1 |
| assets/img/tags/tw2.jpg |      1000002 |      dog |         1 |  2 |
| assets/img/tags/tw5.jpg |      1000004 |   taiwan |         2 |  3 |

Отредактируйте № 1, поскольку ваш URL-адрес отличается, и вы хотите max(id), тогда вы сможете использовать:

SELECT p.url,
  t.name,
  t.num_photo,
  Max(t.id) id
FROM photos p
LEFT JOIN tag_maps AS tm 
    ON p.id = tm.photo_id
LEFT JOIN tags AS t 
    ON t.id = tm.tag_id
group by t.name, t.num_photo  

ОП: Вы можете использовать подзапрос:

SELECT p.url,
    t.name,
    t.num_photo 
FROM
(
    select MAX(created_time) created_time, url, id
    from photos
    group by url, id
)  AS p
LEFT JOIN tag_maps AS tm 
    ON p.id = tm.photo_id
LEFT JOIN tags AS t 
    ON t.id = tm.tag_id

Если значение id в таблице photos уникально для каждой строки, вам может понадобиться использовать следующее:

SELECT p1.url,
    t.name,
    t.num_photo 
FROM photos p1
inner join
(
    select MAX(created_time) created_time, url
    from photos
    group by url
)  AS p2
    on p1.url = p2.url
    and p1.created_time = p2.created_time
LEFT JOIN tag_maps AS tm 
    ON p1.id = tm.photo_id
LEFT JOIN tags AS t 
    ON t.id = tm.tag_id

person Taryn    schedule 14.01.2013
comment
Хорошо, идентификатор на фотографиях уникален, поэтому я использую второй и работает, но зачем группировать по URL-адресу в подзапросе. И есть ли способ без использования подзапроса или других простых методов? - person vzhen; 14.01.2013
comment
@vzhen, если вы не используете GROUP BY url, вы вернете только одну запись с max(created_time), которую хотите различать по каждому url. - person Taryn; 14.01.2013
comment
привет, я просто хочу сказать вам, я только что получил ошибку, и это на самом деле не работает. я отредактировал свой вопрос, не могли бы взглянуть? Спасибо в рекламе - person vzhen; 15.01.2013
comment
Не работает, кажется, max(t.id) не выбирает самое новое created_time. Я снова отредактировал свой вопрос, чтобы быть более ясным. - person vzhen; 15.01.2013
comment
Из запроса сложно сказать, можете ли вы опубликовать структуры таблиц и примеры данных из каждой таблицы? - person Taryn; 15.01.2013
comment
@vzhen Я догадывался о структуре таблицы, поэтому посмотрите мое редактирование с версией, которая, я думаю, будет работать. - person Taryn; 15.01.2013
comment
Ха-ха, БОЛЬШОЕ спасибо за вас. пытался часами, но безуспешно, и спасибо за сторону sqlfiddle. Будет использовать его для вопроса sql в следующий раз. - person vzhen; 15.01.2013