I want to select every photo from my database, then display them grouped by month. I have that code here:
<?php
if (isset($_COOKIE['user_id'])) {
if (!isset($_GET['user_id'])) {
$user_id= $_COOKIE['user_id'];
} else {
$user_id= $_GET['user_id'];
}
$connect= mysqli_connect("localhost", "root", "", "si");
$query= "SELECT * FROM posts WHERE user_id= $user_id ORDER BY date DESC";
$result= mysqli_query($connect, $query)
or die('error with query');
$date = "0";
while ($row= mysqli_fetch_array($result)) {
if ($date != $row['date']) {
echo "<p> ".$row['date']."</p><br/>";
$date = $row['date'];
}
echo '<img src="'.$row['picture']. '"/>' . "<br/>";
}
}
?>
The only problem is that my code displays EVERY image from each month, this makes for an excessively large page. I want to limit my results to only 8 per month (or less if there isn't event 8 pictures for that month), then display a "show more..." link if there are more than 8. I know how to add a LIMIT to my initial query, but that won't work for this scenario. What can I do?
Here is how I want it to look:
add LIMIT $start, $numToDisplay
to your SQL statement, and use PHP to calculate the new values for the $start variable.
e.g. $pageNum = $_GET["page"] and 8 images per page means you can calculate that:
$numToDisplay = 8;
$start = ($pageNum-1)*$numToDisplay;
What you need to do is monitor picture count
$pickLimit = array ();
while ( $row = mysqli_fetch_array ( $result ) ) {
if ($date != $row ['date']) {
echo "<p> " . $row ['date'] . "</p><br/>";
$date = $row ['date'];
}
$pickLimit [$date] = isset ( $pickLimit [$date] ) ? $pickLimit [$date] : 0;
if ($pickLimit [$date] > 7)
continue;
echo '<img src="' . $row ['picture'] . '"/>' . "<br/>";
$pickLimit [$date] ++;
}
This is what is known as "greatest n per group" query. If you search on here there are many examples with different solutions. Here is one of them -
SELECT *
FROM (
SELECT
tmp.*,
#r := IF(#m=DATE_FORMAT(`date`, '%Y%m'), #rank + 1, 1) rank,
#m := DATE_FORMAT(`date`, '%Y%m')
FROM (
SELECT *
FROM posts
WHERE user_id = $user_id
ORDER BY date DESC
) tmp, (SELECT #m:=NULL, #r:=NULL) initvars
) tmp2
WHERE rank <= 8
This could be easily done using the php script whitch you already have and some css tricks, that are also used for creating an animated slider/carousel. Something like this:
<div id="carousel">
<div id="slider">
<?php foreach($images as $img) { ?>
<div class="image">
<img src="<?php echo $img; ?>" />
</div>
<?php } ?>
</div>
</div>
As for the css:
#carousel {
width: 900px; /* how much you need */
height: 100px; /* how much you need */
overflow: hidden;
}
#slider {
width: auto;
height: 100px;
}
.image {
float: left;
}
Related
I need to group all rows with matching roomcode. When I also group resort, it acts like it disables the grouping of roomcode and only gives me the results of the first row with a roomcode.
How can I group the resort column and still group matching roomcode columns? If I ungroup my resort code the query works correctly, but then I can't create separate divs for differing resorts.
The user is searching a date range, hence having multiple rows with the same roomcode, which fetches my points. This is why I am getting the sum of those points. My current way of grouping each resort for output HTML purposes is breaking that. I don't necessarily have to group the resorts, I just need each room at each resort created within its own DIV set. I have a basic example below.
Ideal HTML output
<div id="results">
<div id="resort resortcode">
<div id="roomresults">
<div id="room1"></div>
<div id="room2"></div>
</div>
</div>
<div id="resort2 resortcode2">
<div id="roomresults2">
<div id="room3"></div>
<div id="room4"></div>
</div>
</div>
</div>
This PHP code will group each set of results by resorts, but jacks up my price.
<?php
include("dbh.php");
mysqli_select_db($con, "checkavail") or die ("no database");
$checkin = $_POST['checkin'];
$checkout = $_POST['checkout'];
$occupants = $_POST['occupants'];
$sqlCommand=
"SELECT
MIN(staydate) AS checkin,
MAX(staydate) AS lastnight,
MIN(available) AS available,
ra.resort AS resortcode,
ri.resort,
ri.room,
ri.roomcode,
ri.view,
SUM(ra.points*'20') AS price,
ri.sqfoot,
ri.description,
ri.bedding,
ri.amenities,
ri.sleeps,
ri.sleep_details,
ri.layout_img AS layoutimg,
ri.room_img AS roomimg,
ri.roomimg_thumb
FROM resort_availability AS ra
LEFT JOIN room_info AS ri ON (ra.room = ri.roomcode)
WHERE staydate >= '$checkin' AND staydate = '$checkout'
AND sleeps >= '$occupants'
GROUP BY ri.roomcode
ORDER BY ri.resort, points
";
$result=mysqli_query($con, $sqlCommand) or die(mysqli_error($con));
$data = array();
while($row = $result->fetch_assoc())
{
$itemName = $row["resort"];
$resortCode = $row["resortcode"];
if ( !array_key_exists($itemName, $data)) {
$data[$itemName] = array ();
}
$data[$itemName][] = $row;
}
foreach ($data as $itemName => $rows) {
echo '<div class="resort ' ,$resortCode , '">';
echo '<div class="resort_header"><h1>', $itemName, '</h1></div>';
foreach ($rows as $row){
if ($row['available'] > 0) {
$roomresult = '<div class="room_result roomavailable">';
$available = '<button class="available">BOOK NOW</button>';
$filtavail = 'available';
}
else {
$roomresult = '<div class="room_result roomsoldout" style="">';
$available = '<button class="soldout">SOLD OUT</button>';
$filtavail = 'soldout';
}
echo $roomresult;
echo '<div class="room_thumb"></div>
<div class="room_info"><h4>'
,$row['room'], '-' ,$row['view'] ,
'</h4></div>
<div class="price"><center><h3>','' ,$row['price'],'</h3>' , $available ,'</center></div></div>';
}
echo '</div>';
}
?>
This PHP code gives me accurate results but does not allow me to Create a div with results based on each resort IE, I don't know how to create a Header with the resort name, separating each set of rooms by resort as it is in the first example.
<?php
include("dbh.php");
mysqli_select_db($con, "checkavail") or die ("no database");
$checkin = $_POST['checkin'];
$checkout = $_POST['checkout'];
$occupants = $_POST['occupants'];
$sqlCommand=
"SELECT
MIN(staydate) AS checkin,
MAX(staydate) AS lastnight,
MIN(available) AS available,
ra.resort AS resortcode,
ri.resort AS resort,
ri.room,
ri.roomcode AS roomcode,
ri.view,
SUM(ra.points) AS points,
ri.sqfoot,
ri.description,
ri.bedding,
ri.amenities,
ri.sleeps,
ri.sleep_details,
ri.layout_img AS layoutimg,
ri.room_img AS roomimg,
ri.roomimg_thumb
FROM resort_availability AS ra
LEFT JOIN room_info AS ri ON (ra.room = ri.roomcode)
WHERE staydate >= '$checkin' AND staydate < '$checkout'
AND sleeps >= '$occupants'
GROUP BY ri.resort, roomcode
ORDER BY ri.resort, points
";
$result=mysqli_query($con, $sqlCommand) or die(mysqli_error($con));
while($row = $result->fetch_assoc()) {
$pricecalc = ($row['points'])*20;
$price = number_format($pricecalc, 2);
//RESULTS BOX
if($row['available'] < "1"){
echo '<div id="'.$row['roomcode'].'-'.$row['resortcode'].'"','class="soldout roomresults room'.$row['resortcode'].'">';
}
if($row['available'] > "0"){
echo '<div id="'.$row['roomcode'].'-'.$row['resortcode'].'"','class="available roomresults room'.$row['resortcode'].'">';
}
//IMAGE BOX
echo '<div class="thumbnail"><img height="90" src="',$row['roomimg_thumb'],'">';
echo '</div>';
//ROOM DETAILS
echo '<div class="roomdetails">';
echo '<h4>'.$row['room'].' - '.$row['view'].'</h4>';
echo '<p>Sleeps: '.$row['sleep_details'].'</p>';
echo '<p class="clickfordetails">Click Image For Room Details</p>';
echo '</div>';
//PRICING BOX AND SUBMIT BUTTON
echo '<div class="price">';
echo '<h3>$',$price,'</h3>';
if ($row['available'] < "1"){
echo '<button type="button" class="soldoutbtn">SOLD OUT</button>';
}
if ($row['available'] > "0"){
echo '<button type="button" class="booknowbtn">BOOK NOW</button>';
}
echo '</div,$row>';
echo '</div></div>';
};
?>
Yes group by will give you the 1st record of the same group.
In my understanding , you want to show all the data but place all the records with the same roomcode together.
In that case, please change
GROUP BY ri.roomcode
ORDER BY ri.resort, points
to
ORDER BY ri.roomcode, ri.resort, points
I have managed to output the average rating in a number format, but i would like to output it by using the star method as well.
This is my code so far that outputs the average rating by using numbers;
<?php
$sql = "
SELECT round(avg(`rate`),2) AS `average_rate`, count(`rate`) AS `num_of_rating`
FROM tbl_rating
WHERE hotel_id = '$id' ";
$query = mysqli_query($con,$sql);
$rating = mysqli_fetch_assoc($query);
?>
<div>
<h4 style="color: #1478FF; font-size:30px; font-family: " > <?php echo $rating['average_rate']; ?> Avergae rating </h4>
</div>
For instance;Stars
Please give this a try:
<?php
$sql = "
SELECT round(avg(`rate`),2) AS `average_rate`, count(`rate`) AS `num_of_rating`
FROM tbl_rating
WHERE hotel_id = '$id' ";
$query = mysqli_query($con,$sql);
$rating = mysqli_fetch_assoc($query);
?>
<div>
<h4 style="color: #1478FF; font-size:30px; font-family: " > <?php echo $rating['average_rate']; ?> Average rating </h4>
<?php
$limit = floor($rating['average_rate']);
$remainder = $rating['average_rate'] % 1.0;
for( $i = 0; $i<$limit; $i++ ) {
echo ("<img src=\"\\images\\fullstar.jpg\" />");
}
if ($remainder >= 0.5) echo ("<img src=\"\\images\\halfstar.jpg\" />");
?>
</div>
I'm not sure this will work. I have no way of testing the code, I'm a C# and ColdFusion developer. This is what a few minutes on Google gave me.
To make this work, you need images of a full star called fullstar.jpg and of a half start called halfstar.jpg. They both need to be in a folder names images in your project root.
I have some HTML in a variable that I'd like to loop 4 time per row. I am making a couple of queries first. In one I get the number of rows and store it in a variable. The second, I am looking to fetch the associated data that I will need to display.
$results = $dbCon->query("SELECT * FROM table WHERE status = '1' ORDER BY id DESC LIMIT $start, $limit");
$total = mysqli_num_rows($results);
$res = $dbCon->query($results);
$data = $res->fetch_assoc();
$link = $data['link'];
$title = $data['title'];
$image = $data['image'];
$imgAlt = $data['imgAlt'];
Third, I store what I want to display in a variable. The HTML I plan on displaying looks something like this
$html = printf("<div style=\"text-align:center; max-width:270px; white-space:normal; word-wrap:break-word; border-left:1em solid transparent; border-right:1em solid transparent; text-overflow: ellipsis; float:left;\">
<a href=\"%s\">
<img style=\"width:270px; height:232px; margin-bottom:40px; border-radius:45px; -moz-border-radius:45px; -webkit-border-radius:45px; box-shadow:0px 0px 3px #fff; -moz-box-shadow:0px 0px 3px #fff; -webkit-box-shadow:0px 0px 3px #fff;\" src=\"images/recentshoots/%s\" alt=\"%s\" />
<p>%s</p> <br /></a>
</div>", $link, $image, $imgAlt, $title);
Next, I would like to loop the 20 items per page in 4 items per row. This is where I am having some trouble. My issue is that the number of characters in the $title are always different so the layout breaks apart. At first a tried a simple way using css and php to do a str_pad() but it doesn't seem to work right with empty spaces. I always get some containers that are taller than others which distorts my row. So I did some research in this platform to model after someone else example.
I m having some trouble with what I found because the examples I've seen have information missing that I need to understand how to modify my own. I have seen it done with foreach and while loops. Can someone help me find a way to understand this better?
How can I loop the data retrieved and make sure that only 4 per row exist in a page of 20 items? Thank you so much for your help. I started with something like this
$startingPoint = 1;
echo "<div class=\"row\">";
foreach($startingPoint < 4){ //this foreach is not even starting the right way, how can I fix this?
echo $html;
}
Can I use a foreach? or a while loop? or do-while?
which one is the best solution and the fastest or most efficient way to go? The shorter the code the better.
Foreach loops are used for array datatypes whilst a while loop can be used for booleans and more.
What you're looking for is a for loop, this allows your to set a counter and each time the loop is ran it adds to a counter. Once the expression is met, it ends the loop.
for($i = 1; $i == 4; $i++)
{
echo 'Loop ' . $i . ': This will loop 4 times';
}
However, you could fix your foreach by using this snippet:
$startingPoint = [1,2,3,4];
foreach($startingPoint as $start)
{
echo $html;
}
Since there are 4 items inside the array, the loop will continue 4 times.
Your SQL is returning more than one row of data thus creating $data to become multidimensional, your loop therefore may not work how its written, you could try this:
for($i = 1; $i >= $limit; $i++)
{
print_f(<!-- html here -->, $data[$i]['column']);
}
You can try this code. Full pagination and view:
Example: index.php
<?php
//get page id for pagination and limit query
$limit = 4;
if(isset($_GET["page"]))
$page = intval($_GET["page"]);
else
$page = 1;
$total = $limit * $page;
$start = $total - $limit;
//GEt data from database. I have used mysqli for testing purpose.
$conn=mysqli_connect("localhost","root","","dbname");
$result = mysqli_query($conn, "SELECT * FROM table WHERE status = '1' ORDER BY id DESC LIMIT $start, $limit");
$total = mysqli_num_rows($result);
?>
<!--Your html code what you want-->
<table>
<tr>
<th>Title</th>
<th>Image</th>
<th>Link</th>
</tr>
<!--loop inside html-->
<?php while($data = mysqli_fetch_assoc($result)) { ?>
<tr>
<td><?php echo $data['title']; ?></td>
<td><img src="<?php echo $data['image']; ?>" alt="<?php echo $data['imgAlt']; ?>"> </td>
<td>Link</td>
</tr>
<?php } ?>
</table>
<?php
/**======== Pagination Url generate=============*/
$totalPages = ceil($total/$limit);
if($page <=1 ){
" <span style='font-weight: bold;'> < Prev </span> ";
}else{
$j = $page - 1;
echo " <a href='index.php?page=$j'>Prev</a> ";
}
for($i=1; $i <= $totalPages; $i++){
if($i<>$page){
echo " <a href='index.php?page=$i'>$i</a> ";
}else{
echo " <span style='font-weight: bold;'>$i</span> ";
}
}
if($page == $totalPages ){
echo " <span style='font-weight: bold;'>Next ></span> ";
}else{
$j = $page + 1;
echo " <a href='index.php?page=$j'>Next</a></span> ";
}
?>
The code below has dynamic drop down list, that users chooses preferred brand and model, accordingly the table is generated in the webpage which results of brand, model and year . Now the code needs to group all the same year with different models and highlight them with set of different colors for each year accordingly. An expected results is attached as image.
// (___ & !!!) or (ALL & ___) or (ALL & ALL)
if ((!isset($_POST['model']) || ($_POST['brand'] == 'ALL' && empty($_POST['model']))) || ($_POST['brand'] == 'ALL' && $_POST['sip'] == 'ALL')) {
$query1 = 'SELECT DISTINCT brand,model,year FROM `carlist` ORDER BY brand,model,year';
}
// (... & ...) or (... & ALL)
else if (!empty($_POST['brand']) && (empty($_POST['model']) || ($_POST['model'] == 'ALL'))) {
$query1 = 'SELECT DISTINCT brand,model,year FROM `carlist` WHERE brand="'.$_POST['brand'].'" ORDER BY brand,model,year';
}
// (ALL & ...) or (ALL & notALL)
else if ($_POST['brand'] == 'ALL' && (!empty($_POST['model']) && $_POST['model'] != 'ALL')) {
$query1 = 'SELECT DISTINCT brand,model,year FROM `carlist` WHERE model="'.$_POST['model'].'" ORDER BY brand,model,year';
}
else {
$query1 = 'SELECT DISTINCT brand,model,year FROM `carlist` WHERE brand="'.$_POST['brand'].'" AND model="'.$_POST['model'].'" ORDER BY brand,model,year';
}
//echo $_POST['brand'].'<br />'.$_POST['model'];
echo '<table border=1><tr><th>BRAND</th><th>MODEL</th><th>YEAR</th></tr>';
$result1 = mysqli_query($con, $query1);
while($row1 = mysqli_fetch_array($result1)){
//echo'<tr><td>'.$row1['brand'].'</td><td>'.$row1['model'].'</td><td>'.$row1['year'].'</td></tr>';
$query2= 'SELECT DISTINCT brand,model,year, count(*) `number` FROM `carlist` WHERE brand="'.$_POST['brand'].'" GROUP BY `year` HAVING count(*) > 1';
$result2= mysqli_query($con, $query2);
$count=0;
while($row2 = mysqli_fetch_array($result2)){
if ( $row2['year'] == $row1['year']) {
$count=1;
}
//$intersect = array_intersect($row1,$row2);
//echo $intersect[1];
}
$bgcolor = "#FF8C00";
if($count==1){
echo '<tr style="background-color: tomato;" ><td>'.$row1['brand'].'</td><td>'.$row1['model'].'</td><td>'.$row1['year'].'</td></tr>';
}else {
echo'<tr><td>'.$row1['brand'].'</td><td>'.$row1['model'].'</td><td>'.$row1['year'].'</td></tr>';
}
}
echo '</table>';
Create function what generates random color
function getColor($year){
return '#'.substr(md5($year), 0, 6);
}
In your while loop
// Get color for current year
// Same years will be colored with same color
$bgColor = getColor($row1['year']);
// Print table row
echo '<tr style="background-color: '.$bgColor.';"><td>'.$row1['brand'].'</td><td>'.$row1['model'].'</td><td>'.$row1['year'].'</td></tr>';
So your while loop will be
while($row1 = mysqli_fetch_array($result1)){
// Delete extra while and if condition
$bgColor = getColor($row1['year']);
echo '<tr style="background-color: '.$bgColor.';"><td>'.$row1['brand'].'</td><td>'.$row1['model'].'</td><td>'.$row1['year'].'</td></tr>';
}
NOTE: Your queries are vulnerable to SQL injection. Please see this answer on how to prevent it.
NOTE 2: Since your background colors are generated automatically, it may happen that text is not easily readable.
Method 1:
This won't need to do a nested loop. This first method will only work if your row is arranged by year.
/* DEFINE THIS VARIABLE FIRST BEFORE YOUR LOOP */
$yearstorage = ""; /* STORAGE FOR YOUR YEAR AND COMPARISON LATER */
$randomcolor = '#' . strtoupper(dechex(rand(256,16777215))); /* GENERATE RANDOM COLOR */
/* START OF YOUR LOOP */
while($row1 = mysqli_fetch_array($result1)){
$res = mysqli_query($con,"SELECT * FROM carlist WHERE year=".$row1['year']."");
if(mysqli_num_rows($res) > 1){ /* IF YEAR HAS ONLY ONE ROW */
$randomcolor = "#ffffff";
}
if(empty($yearstorage)){ /* START OF FIRST ROW */
?>
<tr style="background-color: <?php echo $randomcolor ?>;">
<?php
$storecolor = $randomcolor;
}
else if($yearstorage == $row1["year"]){ /* IF LAST YEAR ROW IS THE SAME AS THE CURRENT YEAR ROW */
?>
<tr style="background-color: <?php echo $storecolor ?>;">
<?php
}
else { /* IF THE LAST YEAR ROW IS NOT THE SAME WITH THE CURRENT YEAR ROW */
$randomcolor = '#' . strtoupper(dechex(rand(256,16777215))); /* GENERATE NEW RANDOM COLOR */
?>
<tr style="background-color: <?php echo $randomcolor ?>;">
<?php
$storecolor = $randomcolor;
}
$yearstorage = $row1["year"]; /* STORE THE CURRENT YEAR FOR COMPARISON ON THE NEXT LOOP */
?>
<td><?php echo $row1['brand']; ?></td>
<td><?php echo $row1['model']; ?></td>
<td><?php echo $row1['year']; ?></td>
</tr>
<?php
} /* END OF WHILE LOOP */
Method 2:
This second method will work even if your row is not arrange in year. Even if arranged by different column name which I would refer more to you.
You have to create a loop to get all the year distinctly, and store the color and year in an array, and compare and get them on your main loop.
No need to do a nested loop also. But two separated loop.
As you will notice, this code is also shorter than the first method.
If a year contains one row only, it will have a white background.
$counter = 0; /* DETERMINER OF THE COLOR TO BE USED LATER */
$res = mysqli_query($con,"SELECT DISTINCT year FROM carlist");
while($row = mysqli_fetch_array($res)){
$randomcolor = '#' . strtoupper(dechex(rand(256,16777215))); /* GENERATE NEW RANDOM COLOR */
/* STORE THE COLOR AND YEAR IN AN ARRAY */
$res2 = mysqli_query($con,"SELECT * FROM carlist WHERE year = ".$row['year']."");
if(mysqli_num_rows($res2) > 1){ /* IF YEAR IS USED MORE THAN ONCE */
$colorstorage[$counter] = $randomcolor;
}
else { /* ELSE, IT WILL HAVE A WHITE BACKGROUND */
$colorstorage[$counter] = "#ffffff";
}
$yearstorage[$counter] = $row['year'];
$counter = $counter + 1; /* INCREMENT COUNTER */
} /* END OF LOOP THAT STORES THE COLOR AND YEAR IN AN ARRAY */
/* START OF YOUR MAIN LOOP */
while($row1 = mysqli_fetch_array($result1)){
$key = array_search($row1["year"],$yearstorage);
?>
<tr style="background-color: <?php echo $colorstorage[$key]; ?>;">
<td><?php echo $row1['brand']; ?></td>
<td><?php echo $row1['model']; ?></td>
<td><?php echo $row1['year']; ?></td>
</tr>
<?php
} /* END OF YOUR MAIN LOOP */
I'm working on an event scheduler site and I am currently stuck as I'm using a Months table (with id & month as the headers) to group my results by month. Due to this, if I try to schedule an event for January 2016, it successfully puts it into the month I choose as intended, but understandably puts it into 2015.
I'm looking to get some help on extending this beyond the end of the current year and adding functionality for different years.
I would happily use another method than using my current table setup, so any tips or suggestions would be appreciated.
Current code is as follows:
<?php include 'includes/connect.php';
include 'includes/header.php';
$curMonth = date("n"); ?>
<b>Upcoming Trip Information:</b><br><br>
<?php
$res = mysql_query("SELECT * FROM months ORDER BY id");
while ($rows = mysql_fetch_array($res)) {
if($rows['id'] >= $curMonth ){
$monthname = $rows['month']; ?>
<table cellpadding="0" cellspacing="3" width="100%">
<tr>
<td>
<?php
$tid = $_GET['transporter'];
$check = mysql_query("SELECT * FROM trips WHERE monthname(start_date) = '" . $rows['month'] . "' AND tid = '$tid'");
$check = mysql_num_rows($check);
if ($check < 1) {
echo "";
} else { ?> <h2><?php echo $monthname; ?><?php } ?></h2></td></tr> <tr> <?php $cmonth = date('F');
$tid = $_GET['transporter'];
$res1 = mysql_query("SELECT * FROM trips WHERE monthname(start_date) = '$monthname' ORDER BY start_date");
while ($rows = mysql_fetch_array($res1)) {
$trid = $rows['trid'];
$trip_start = $rows['trip_start'];
$trip_end = $rows['trip_end'];
$start_date = $rows['start_date'];
$end_date = $rows['end_date'];
$colour = $rows['colour'];
$stime = strtotime($start_date);
$startt = date("l jS", $stime);
$etime = strtotime($end_date);
$endt = date("l jS", $etime); ?>
<td valign="middle" style="height: 100px; background-color: #4b99ed; text-align: center;">
<div style="font-size: 17px; color: #ffffff;"><?php echo $trip_start; ?> to <?php echo $trip_end; ?></div>
<div style="font-size: 15px; color: #ffffff;"><?php echo $startt; ?> - <?php echo $endt; ?></div>
</td>
<?php } } } ?>
</tr>
</table> <?php include 'includes/footer.php'; ?>
If possible I would like to maintain the results layout..
You could try, instead of using a months table, using the start_date column of your trips table.
Try changing your query:
SELECT trips.*, DATE_FORMAT('%M, %Y', start_date) as `dt`
FROM trips
WHERE tid = '$tid' /* This is bad, please prepare or escape your variables*/
ORDER BY `dt` ASC
You then won't have to do the first query to get all the months and loop through them. If you must have empty containers for each month, try using that query, but loop through a PHP-generated array of months to display.