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
Related
I am working on creating a drop down button that lets one select the year from a list of options in order to sort through a data table. The code (reproduced below) keeps repeating the last year available, I can't seem to figure out why it is doing this. I am using PHP to pull from a MySql database.
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Select Year</button>
<div id="myDropdown" class="dropdown-content">
<?php
$year = array();
while($subject = mysqli_fetch_assoc($subject_set)) {
$i=0;
$exists = 0;
$n = count($year);
while($i < $n){
if ($subject['year'] == $year[$i]){
$exists = 1;
}
$i++;
}
if($exists == 0){
$year[$n] = $subject['year'];
echo " {$subject['year']} ";
}
}
$subject_set = find_all_subjects();
?>
</div>
</div>
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 define a counter in while loop and it is initialized outside the loop.
I have echo the counter in loop itself. When I have 50 record on first page it displays 1 to 25. The problem is that on second page it start again from 1, not like it should work: to start it from 26 to 50.
Here is my code:
<?php
//show records
$query = mysqli_query($con,"SELECT table2.col2 AS a,table1.col2 AS b, table1.col1 AS c, table1.q_url AS d FROM {$statement} LIMIT {$startpoint} , {$limit}");
$Authorname='';
$count=1;
while ($row = mysqli_fetch_array($query)) {
$output='';
$Authorname =$row['a'];
$url = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$url=explode('/',$url);
?>
<div class="record round"><?php echo $count;$output .='<a href="http://localhost/quotes/'.$url[5].'/'.$row['d'].'.html">';
echo $output .=$row['b'].'</a>';?></div>
<?php
$count++;
}
?>
Edit
Try
$nbpage = 2;
$nbresultperpage=25;
$count = ($nbpage-1)*$nbresultperpage;
Where $nbpage is you're current number of page
<div class="row">
<?php
$r=mysql_query("SELECT * FROM advertisements WHERE $filter exposure!='0' AND `status`='2' AND (clicks_left_micro>0 OR clicks_left_mini>0 OR clicks_left_standard>0 OR clicks_left_extended>0) ORDER BY exposure DESC");
while($ar=mysql_fetch_array($r)):
echo "<div class='span4'> text here text here</div>";
endwhile;
?>
</div>
As you can see in the $r query, I am ordering by exposure. The exposure field can contain the numbers from 1-3. What I am trying to do is to create a new row for each exposure number. Example:
Advertisements that have exposure = 1, will be in the first row
Below that, will be advertisements that have exposure = 2
And last, there will be advertisements that have exposure = 3
The way it is now, the advertisements/span4 divs are just being echoed out next to each other. I want to sort them inside the while loop in <div class='row'></div>
What about something like this:
<div class="row">
<?php
$r=mysql_query("SELECT * FROM advertisements WHERE $filter exposure!='0' AND `status`='2' AND (clicks_left_micro>0 OR clicks_left_mini>0 OR clicks_left_standard>0 OR clicks_left_extended>0) ORDER BY exposure DESC");
$row1 = '';
$row2 = '';
$row3 = '';
while($ar=mysql_fetch_array($r)):
if($ar['exposure'] == 1)
$row1 .= '<span>Your code here for row 1</span>';
else if($ar['exposure'] == 2)
$row2 .= '<span>Your code here for row 2</span>';
else if($ar['exposure'] == 3)
$row3 .= '<span>Your code here for row 3</span>';
endwhile;
?>
<table>
<tr>
<td><?php echo $row1; ?></td>
<td><?php echo $row2; ?></td>
<td><?php echo $row3; ?></td>
</tr>
</table>
</div>
Of course you will have to adjust it to your needs, but this is the idea.
EDIT: As some other people have noticed, you should not use mysql_* functions anymore.
Since they are ordered by exposure, you can simply do :
$curExpo = null;
while( ... ) {
if( $curExpo !== $row['exposure']) {
create new row
$curExpo = $row['exposure'];
}
}
I have been working on trying to get a bunch of data to work in a table structure displayed neatly using PHP, and I must say I am having a difficult time. I have finally been able to call the columns so that in case I add a field it will always add it in my table, and I hope for this to be very easily managed. However, when I initially set up the table, I put it in a random order. Now when I come use the DESCRIBE table it gives them to me in exact order, and I cannot find a way to organize them better. It would not make sense to say have month/year at the end of the database for my form that I have.
<?php
require 'connect.php';
?>
<h3>Monthly Finances | Add New Month </h3>
<table border="1" bordercolor ="#000000">
<tr>
<?php
$columns = "DESCRIBE `month` ";
if($query_run_columns = mysql_query($columns)){
$columnNames = array();
while($column = mysql_fetch_assoc($query_run_columns)){
echo '<th>'.$column['Field'].'</th>';
}
}else{
echo'sql error';
}
?>
<?php
$gatherdata = "SELECT `month`, `year`,`rent`,`electric`,`cable`,`cellphone`,`renters` FROM `month` ";
if($query_run = mysql_query($gatherdata)){
while($row = mysql_fetch_assoc($query_run)){
$rent = $row['rent'];
$electric = $row['electric'];
$cable = $row['cable'];
$cellphone = $row['cellphone'];
$renters = $row['renters'];
$month = $row['month'];
$year = $row['year'];
echo '<tr>';
echo '<td align="center">'.$month.'</td>';
echo '<td algin="center">'.$year.'</td>';
echo '<td align="center">'.$rent.'</td>';
echo '<td align="center">'.$electric.'</td>';
echo '<td align="center">'.$cable.'</td>';
echo '<td align="center">'.$cellphone.'</td>';
echo '<td align="center">'.$renters.'</td>';
echo '</tr>';
}
}else{
echo 'query error';
}
?>
<br>View by month
</table>
<form action="index.php" method="GET">
<select name="months" value="all">
<?php
$gathermonths = "SELECT `month`, `year` FROM `month";
if($query_month_selector = mysql_query($gathermonths)){
while($month_row = mysql_fetch_assoc($query_month_selector)){
$month = $month_row['month'];
$year = $month_row['year'];
echo '<option value="'.$month.' '.$year.'">' .$month.' '.$year.'</option>';
}
}
echo $_GET['months'];
?>
<input type="submit" value="View Selected Date"></input>
</select>
</form>
My code is very far from complete, or orderly but I have been slacking on this project and I will clean it up more when I have more time. But if you could please give me a hand on an efficient organizational method that would be appreciated.
Do your tables contain an index/id?
You can easily order them in ascending/descending by "ORDER BY"
ALTER TABLE `table_name` ORDER BY `id`
Note default ORDER BY is in ascending order. Put DESC at the end if you want descending.
If you want your mysql query to output results in a nice ordered fashion, you can also use ORDER BY in the query:
$gathermonths = "SELECT `month`, `year` FROM `month` ORDER BY `month` DESC";
There is also GROUP BY functions in case you wanted to group your results by month:
$gathermonths = "SELECT `month`, `year` FROM `month` GROUP BY `month`";
Instead of the DESCRIBE query, you could use mysql_fetch_field. Then columns will always be in the same order you have on your SELECT:
<?php
$gatherdata = "SELECT `month`, `year`,`rent`,`electric`,`cable`,`cellphone`,`renters` FROM `month` ";
if($query_run = mysql_query($gatherdata)){
// Loop the columns to build the table headers
echo '<table>';
echo '<tr>';
while ($i < mysql_num_fields($query_run)) {
$field = mysql_fetch_field($query_run, $i);
echo '<th>' . $field->name . '</th>';
$i++;
}
echo '</tr>';
// Your current data loop
while($row = mysql_fetch_assoc($query_run)){
// (...)
}
echo '</table>'
}
?>
Since you're already specifying which columns you're fetching, simply output the column headers explicitly rather than querying the database.
Contrariwise, if you want to abstract the HTML table generation code so that it works with arbitrary SQL tables (thus separating data access from display), record the column names as you generate the column headers in an array, then iterate over this array when outputting rows. You can also do away with the $rent = $row['rent']; assignments, as they gain you nothing. Using PDO:
/* data access */
$finances = $db->query('SELECT `month`, `year`,`rent`,`electric`,`cable`,`cellphone`,`renters` FROM `month`');
$columns = array();
for ($i = 0; $i < $finances->columnCount(); ++$i) {
$meta = $finances->getColumnMeta($i);
$columns[$meta['name']] = ucwords($meta['name']);
}
/* data display. Note this is completely independent of the type used to store
the colum & row data. All that matters are that $columns and $finances are
Traversable
*/
?>
<table>
<thead>
<tr>
<?php foreach ($columns as $name => $label): ?>
<th><?php echo $label ?></th>
<?php endforeach ?>
</tr>
</thead>
<tbody>
<?php foreach ($finances as $monthly): ?>
<tr>
<?php foreach ($columns as $name => $label): ?>
<td><?php echo $monthly[$name]; ?></td>
<?php endforeach ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
Error handling and abstraction into modules left as an exercise.