You can write:
SELECT computers.name,
computers.status,
computers.timestamp
FROM ( SELECT name,
MAX(timestamp) AS max_timestamp
FROM computers
GROUP
BY name
) AS t
JOIN computers
ON computers.name = t.name
AND computers.timestamp = t.max_timestamp
;
The above uses this subquery to finds the greatest timestamp for each name:
SELECT name
MAX(timestamp) AS max_timestamp
FROM computers
GROUP
BY name
;
and then it gathers fields from computers whose name and timestamp match something that the subquery returned.
The reason that your order by clause has no effect is that it comes too "late": it's used to order records that are going to be returned, after it's already determined that they will be returned. To quote from §11.16.3 "GROUP BY and HAVING with Hidden Columns" in the MySQL 5.6 Reference Manual on this subject:
The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate. Furthermore, the selection of values from each group cannot be influenced by adding an ORDER BY clause. Sorting of the result set occurs after values have been chosen, and ORDER BY does not affect which values the server chooses.
Another way is to write a correlated subquery, and dispense with the GROUP BY entirely. This:
SELECT name, status, timestamp
FROM computers AS c1
WHERE NOT EXISTS
( SELECT 1
FROM computers
WHERE name = c1.name
AND timestamp > c1.timestamp
)
;
finds all rows in computers that haven't been superseded by more-recent rows with the same name. The same approach can be done with a join:
SELECT c1.name, c1.status, c1.timestamp
FROM computers AS c1
LEFT
OUTER
JOIN computers AS c2
ON c2.name = c1.name
AND c2.timestamp > c1.timestamp
WHERE c2.name IS NULL
;
which is less clear IMHO, but may perform better.