Data for the latest previous effective date sub query
So I'll provide two answers, with the following caveats:

Certain DB engines are bad with correlated subqueries, either in terms of performance or outright lack of support
The row identifier (id) columns carelessly tacked on as a &quot;primary key&quot; will limit performance of both solutions and will likely force a sort, an expensive operation

Given the lack of proper primary keys, the performance may suffer if you are working on a large set of data.  If you're just returning a few hundred/few thousand rows you should be okay on modern hardware.
Methond 1: Correlated Subquery
The most direct way (from a code perspective) is to use a correlated subquery to select the record from journal with the greatest updated_on less than or equal to spent_on from time_entry:
SELECT
  time_entry.id
 ,issue.subject
 ,time_entry.spent_on
 ,time_entry.hours
 ,journal.done_ratio
FROM
  time_entry time_entry 
INNER JOIN
  issue issue
    ON issue.id = time_entry.issue_id
LEFT JOIN
  journal journal
    ON journal.issue_id = time_entry.issue_id
         AND journal.updated_on =
           (
             SELECT
               MAX(updated_on)
             FROM
               journal
             WHERE
               issue_id = time_entry.issue_id
                 AND updated_on &lt;= time_entry.spent_on
           )

Method 2: Window Function
You can also use a windowing function to number the rows according to specified criteria, and selecting only the first row.  This forces a sort in all instances.
SELECT
  id
 ,subject
 ,spent_on
 ,hours
 ,done_ratio
FROM
  (
    SELECT
      time_entry.id
     ,issue.subject
     ,time_entry.spent_on
     ,time_entry.hours
     ,journal.done_ratio
     ,ROW_NUMBER() OVER (PARTITION BY time_entry.id ORDER BY journal.updated_on DESC) AS rownum
    FROM
      time_entry time_entry 
    INNER JOIN
      issue issue
        ON issue.id = time_entry.issue_id
    LEFT JOIN
      journal journal
        ON journal.issue_id = time_entry.issue_id
             AND journal.updated_on  &lt;= time_entry.spent_on
  ) x
WHERE
  rownum = 1