Q:

php loop through MySQL records - make decision based on row value

I am using this code to loop through MySQL rows:
$sql = "SELECT * FROM vwPublicServices2 ORDER BY Service_Date__c, 
Service_Time__c";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    echo "<table><tr><th>Service Date</th><th>Service Time</th>
    <th>Church</th><th>Service</th><th>Service Leader</th></tr>";

    while($row = $result->fetch_assoc()) {    

       // insert header stuff on change of $date1
       if ($row["ServiceDate"] <> $date1) { 

          echo $row["ServiceDate"]. "(".$date1.")"."<br/>";

          echo "<tr><td>" . $row["ServiceDate"]. "</td><td>" . 
          $row["Service_Time__c"]. "</td><td>" . $row["Location__c"]. "</td>
          <td>" . $row["PublicName"]. "</td><td>" . $row["FullName"]."</td>
          </tr>";

          // set $date1 = row ServiceDate
          $date1 = $row["ServiceDate"];  

        } else {

          //  echo row data to follow on previous - i.e date has not 
          changed
          echo "<tr><td>" . 
          $row["ServiceDate"]. "</td><td>" . 
          $row["Service_Time__c"]. "</td><td>" .
          $row["Location__c"]. "</td><td>" .
          $row["PublicName"]. "</td><td>" . 
          $row["FullName"]."</td></tr>";

        }

     }
     echo "</table>";
  } else {
     echo "0 results";
}

$conn->close();

Every time row["ServiceDate"] changes I want to insert some header data.
Here are some of the results:

There are two things I cannot understand - why is the date check 'one date out' i.e in the second line why is 14/05/2017 compared to 13/05/2017 ?
Also, why does the second echo statement not appear ?
I think I am missing some fundamental point with the way the while loop works !  Any help here much appreciated.  Thanks.
Here is an illustration of the header insertion on date change using similar data to above. (This web page pulls data from Salesforce  via their API and uses a similar date check to the one in the MySQL code above - but it loops through the data with a For..Each loop )

A:

You need to output your header only when the date changes. Because the data row needs to be displayed all the time (for each each row) it does not need to be in the if condition at all. 
Your code should look something like this:
if ($result->num_rows > 0) {
    echo "<table>";

    while($row = $result->fetch_assoc()) {    

       // insert header stuff on change of $date1
       if ($row["ServiceDate"] <> $date1) { 

           echo "<tr><th>".$row["ServiceDate"]. "(".$date1.")"."</th></tr>";
           echo "<tr><th>Service Date</th><th>Service Time</th>
    <th>Church</th><th>Service</th><th>Service Leader</th></tr>";

            $date1 = $row["ServiceDate"]; 

        } 

          //  echo row data 
          echo "<tr><td>" . 
          $row["ServiceDate"]. "</td><td>" . 
          $row["Service_Time__c"]. "</td><td>" .
          $row["Location__c"]. "</td><td>" .
          $row["PublicName"]. "</td><td>" . 
          $row["FullName"]."</td></tr>";

     }
     echo "</table>";
  } else {
     echo "0 results";
}

