Optimize MySQL double select inside for-loop
Three major points:


Executing SQL queries in a loop will nearly always cause a performance problem.  You want to formulate a query that gives you all the data you want.
mysql_query() and similar functions are deprecated; use mysqli or PDO instead.
Composing your query by concatenation and interpolation, without escaping, could easily lead to an SQL injection vulnerability.  Better yet, use a database interface that supports placeholders for parameters so that you don't have to worry about escaping.


A better solution would go something like this:

function bookings_between($booking_state, $start, $end) {
    $formattedStart = date('Y-m-d', $start);
    $formattedEnd   = date('Y-m-d', $end);

    $query = mysql_query("
        SELECT the_date, COUNT(id)
            FROM ".T_BOOKINGS."
            WHERE id_state=$booking_state
                $sql_condition AND
                the_date BETWEEN '$formattedStart' AND '$formattedEnd'
            GROUP BY the_date;")
        or die ("Error getting states&lt;br&gt;".mysql_error());

    $results = array();
    while ($row = mysql_fetch_array($query, MYSQL_NUM)) {
        $results[$row[0]] = $row[1];
    }
    return $results;
}

$booked = bookings_between(1, $start, $end);
$reserved = bookings_between(4, $start, $end);


The results are not in the same format as your original.  This returns the bookings in associative arrays, keyed by the date (as formatted by MySQL).  Days that have no bookings will not have an entry.  If you need to, you can post-process $booked and $reserved back into a data structure compatible with the original code.  The big win, though, is that you execute just two queries instead of two queries per day of the period in question.