2015-10-15 2 views
4

У меня есть две таблицы Service и Status. Сервиз держит только name и idSQL Выбор из двух таблиц с внутренним соединением и пределом

| id | name | 
|----|-------| 
| 1 | Test1 | 
| 2 | Test2 | 

И таблица состояния, как этот

| id | status | service_id |     timestamp | 
|----|--------|------------|---------------------------| 
| 1 |  OK |   1 | October, 15 2015 09:03:07 | 
| 2 |  OK |   1 | October, 15 2015 09:08:07 | 
| 3 |  OK |   2 | October, 15 2015 10:05:23 | 
| 4 |  OK |   2 | October, 15 2015 10:15:23 | 

Я хочу, чтобы получить данные, как этот

| id | name | status |     timestamp | 
|----|-------|--------|---------------------------| 
| 1 | Test1 |  OK | October, 15 2015 09:08:07 | 
| 2 | Test2 |  OK | October, 15 2015 10:15:23 | 

последнее состояние с служебные данные. Я попытался это заявление

SELECT ser.id, ser.name, a.status, a.timestamp 
from Service ser 
    inner join (select * from status 
       order by Status.timestamp 
       DESC limit 1) as a 
    on a.service_id = ser.id 

Но я только получаю

| id | name | status |     timestamp | 
|----|-------|--------|---------------------------| 
| 2 | Test2 |  OK | October, 15 2015 10:15:23 | 

Как я могу изменить заявление, чтобы получить то, что я хочу?

Для тестирования SQL Fiddle

+1

Добавлены 'mysql' тега на основе СУБД, используемой в SQLFiddle –

+0

Вы хотите последний статус для каждой службы? – jarlh

+0

@jarlh да это то, что я хочу – ScreamingTree

ответ

1

Вы можете сделать это:

SELECT 
    ser.id, 
    ser.name, 
    s.status, 
    s.timestamp 
FROM Service ser 
INNER JOIN status as s ON s.service_id = ser.id 
INNER JOIN 
(
    SELECT 
    service_id, 
    MAX(timestamp) AS MaxDate 
    FROM status 
    GROUP BY service_id 
) AS a ON a.service_id = s.service_id 
     AND a.MaxDate = s.timestamp; 

Соединить с подзапроса:

SELECT 
    service_id, 
    MAX(timestamp) AS MaxDate 
FROM status 
GROUP BY service_id 

устранит все статусы, кроме того, с последней датой.

+0

Спасибо, это работает очень хорошо :) – ScreamingTree

1

Для каждой службы, используйте NOT EXISTS вернуть статус только тогда, когда не позднее один не существует:

select ser.id, ser.name, st.status, st.timestamp 
from service ser 
    left join status st1 on ser.id = st1.service_id 
where not exists (select 1 from status st2 
        where st2.service_id = st1.service_id 
        and st2.timestamp > st1.timestamp) 

Необязательно делать LEFT JOIN также возвращать услуги без какого-либо статуса. Перейдите на страницу JOIN, если это не нужно.

0

Попробуйте это ...

SELECT ser.id, ser.name, a.status, a.max_timesatmp_rm 
from Service ser 
    inner join (select *,row_number() over (partiton by service_id order by timestamp desc) as max_timesatmp_rm from status 
      ) as a 
    on a.service_id = ser.id 
    where a.max_timesatmp_rm=1; 
0

Вы можете получить этот результат без подзапроса как этот

SELECT s.id, s.name, 
SUBSTRING_INDEX(GROUP_CONCAT(st.status ORDER BY st.timestamp DESC),',',1) AS status_value, 
SUBSTRING_INDEX(GROUP_CONCAT(st.timestamp ORDER BY st.timestamp DESC),',',1) AS time_stamp 
FROM Service s 
JOIN Status st ON(st.service_id = s.id) 
GROUP BY s.id 
ORDER BY s.id 

Выход

id name status_value time_stamp 
1 Test1 OK   2015-10-15 09:08:07 
2 Test2 OK   2015-10-15 10:15:23 
0

Вы можете получить результат, используя этот запрос

SELECT MAX(s.id), 
    sr.id, 
    sr.name, 
    s.status, 
    s.timestamp 
FROM Service AS sr 
INNER JOIN status AS s ON s.service_id = sr.id 
GROUP BY sr.id 
ORDER BY s.id ASC 

Я думаю, что это будет работать для вас

Смежные вопросы