I have "reservation" table (mySql) that contain number of columns: res_id, hotel_id, hotel_name, from_date, to_date.
I would like to select and print html table for each hotel (i'm using PHP). the result should be a title - the name of the hotel, and bellow it a list of reservation for the specific hotel.
I can do GROUP BY:
Select * FROM reservation GROUP BY hotel_id
I'm not sure if it's the right way to do it, and how do i print the results without checking all the time if the hotel_id was changed?
Thank you in advanced
GROUP BY is definitely NOT the right way to approach this. One method would be:
SELECT *
FROM reservation
ORDER BY hotel_id;
You would then loop through the result sets. When the hotel name changes, you would put in the title of the hotel.
Note: This is a poor data model if it has both the hotel id and name in reservation. This would normally be in hotel and you would connect the tables using JOIN:
SELECT h.hotel_name, r.*
FROM hotels h JOIN
reservation r
ON r.hotel_id = h.hotel_id
ORDER BY hotel_id;
Using a LEFT JOIN, you can even get hotels with no reservations.
How is it that the hotel_id would change? As per your question it seems that hotel_id is a column made for join with a "hotels" table, isn't it?
Regarding the "group by", why would you group by hotel? This would make you loose reservations data, unless you were using some sort of group_concat.
If you want to get the reservations from a specific hotel you could loop through your hotels table and inside your loop you can do:
SELECT * FROM reservations WHERE hotel_id='QUERIED_HOTEL_ID'
Then show the results.
Or you could simply
SELECT * FROM reservations
And when you get the fetched results you can make a multidimensional php array with 'hotel_id' as top level key and 'res_id' as secondary, like this:
$reservations_by_hotel = [];
do {
$resId = $row['res_id'];
$hotelId = $row['hotel_id'];
$reservations_by_hotel[$hotelId][$resId] = $row;
} while ($row = $result->fetch_assoc());
Related
I was wondering if it was possible to run a query inside a while loop which is used to display the content of a SQL table.
Here is the code if I'm not clear enough :
$sql="SELECT * FROM hotels WHERE rooms>0";
$req=$db->query($sql);
while($row=$req->fetch()){
//The second query to check how many place is left
$req2=$db->query('SELECT COUNT(*) FROM people WHERE idhotels='.$row["idhotels"].';');
echo "hey".$req2;
$left_rooms= $row["rooms"] -$req2;
echo '<option value="'.$row["idhotels"].'">'.$row["name_hotel"].' ('.$left_rooms.' rooms left)</option>';
}
What I'm trying to do here, is to display a list of hotels with the number of rooms left. The problem is I have to count how many rooms are taken before displaying the number of rooms left, hence the second request.
My code obviously doesn't work, but I can't figure out why.
Can someone help me ?
Many thanks !
Why not using a join and a group by so you only have one query ?
$sql="SELECT h.idhotels,h.name_hotel,count(*) FROM hotels h inner join people p on h.idhotels = p.idhotels WHERE h.rooms>0 group by h.idhotels,h.name";
while($row=$req->fetch()){
// Here do whatever you want with each row
}
Have you tried to calculate your left rooms in the database with a joined query like:
SELECT rooms - COUNT(*) AS left_rooms FROM hotels h WHERE rooms > 0 JOIN people p ON (p.idhotels = h.idhotels) GROUP BY h.idhotels, h.name ORDER BY left_rooms ASC;
I checked through a few different questions previously asked but they were more advanced than what I need at the moment. I need a simple way to join two tables and display the results so that I can then manipulate them in any way I want once it is collecting the data the way I need it to. The code below is very simple... Yet I am having trouble. First I create a class that connects to the database then I created a method to query the database and join to tables based on common columns. After that I would like the loop to go through the top four results based on their title name which are 'gold', 'silver', 'platinum', 'palladium' I just want to make sure that the join request is working. Please view the code below and maybe you can tell me why the results I keep getting are
1 Gold
1 Gold
1 Gold
1 Gold
Literally I get Gold 4 times when I need a list of all 4 precious metals.I thought that when the while loop runs through I would get each one as it is supposed to run through all 4 rows and there are no more yet it runs through the same 1st row and brings back 1 Gold every time. Both the id and the metals title name. If I am missing something please feel free to ask and I will add it for you if it helps.
class testJoin{
public function __construct($dbCon){
$this->dbConnection = $dbCon;
}
function testingJoin($dbCon) {
if($results = $this->dbConnection->query("SELECT metal.id, metal.title, price.metalId FROM metal INNER JOIN price ON metal.id = price.metalId ORDER BY metal.title LIMIT 0,4")){
while($data = $results->fetch_assoc()){
printf("<p style=\"display:inline;\">%s</p>
<p style=\"display:inline;\">%s</p><br />", $data['id'], $data['title']);
}
}
$dbCon->close();
}
}
JOIN creates a cross-product of the matching rows in the two tables. If there are multiple price rows for each metal, you'll get all those different prices, and then you take the first 4 rows of this.
If you want to limit the number of metals, but not the total number of rows, you can join with a subquery:
SELECT metal.id, metal.title, price.metalId
FROM (SELECT id, title
FROM metal
ORDER BY title
LIMIT 4) AS metal
JOIN price ON metal.id = price.metalId
Or if you want to get just one row per metal, you can use GROUP BY
SELECT metal.id, metal.title, price.metalId
FROM metal
JOIN price ON metal.id = price.metalId
GROUP BY metal.id
ORDER BY metal.title
LIMIT 4
Here you have no reason to join to prices table at all
SELECT metal.id, metal.title
FROM metal
ORDER BY metal.title
Cos u added to result nothing from there.
If u really need join to prices and display results by "not repeated" metal names, u should just GROUP results
SELECT metal.id, metal.title
FROM metal
INNER JOIN price ON (metal.id = price.metalId)
GROUP BY metal.id
ORDER BY metal.title
After that you can retrieve some useful data from prices table, for example average price for each metal
SELECT metal.id, metal.title, AVG(price.price) AS metal_price
FROM metal
INNER JOIN price ON (metal.id = price.metalId)
GROUP BY metal.id
ORDER BY metal.title
Also you should understand difference between LEFT JOIN and INNER JOIN.
LEFT - will fetch ALL needed rows from first table (metal) and add results from second (prices) even if there is no such metal in prices table (then results from second table will be NULL). (metal.id = price.metalId) can be understanded as "ALL metals with some prices, if they have"
INNER - will fetch ONLY those rows from first table which are presented in second table, by "JOIN ON" condition. (metal.id = price.metalId) can be understanded as "THOSE metals WHICH HAVE prices"
https://pp.vk.me/c623725/v623725696/14ae4/459rNGJwMJc.jpg
Hi I am new for developing.Kindly bear my codings. I have created a table arlog with id(auto increment), status, ticket number and code. Ticket and code number is set as unique. That is the duplicate of this combination cannot inserted again. But individually ticket number or cpt can be inserted as many times.It works fine. Now I want to use select query with another table with respect to the arlog table ticket number and code.Here is the select statement
$result = mysql_query("SELECT * FROM `ar` C WHERE provider='".$_SESSION['PROVIDER']
."' AND C.`TicketNo` IN ( SELECT TicketNo FROM `arlog` L where L.status NOT IN('New','Completed','Completed(Ar_aging)
','Completed(Rework)','Rework','Completed_Followup','Completed_Supervising' )
and L.assign='".$_SESSION['NAME']."' ) order by id desc") or die(mysql_error());
The query check the ticket number in arlog and displays correcly. But I want to combine TicketNo and Code in the arlog. I have made research but could not find solution. First of all is it possible?
Please try following sql:
SELECT L.TicketNo ,L.Code,C.* FROM `ar` C left join `arlog` L ON C.TicketNo = L.TicketNo where C.provider='your condition' and L.status NOT IN('New','Completed','Completed(Ar_aging)','Completed(Rework)','Rework','Completed_Followup','Completed_Supervising' ) and L.assign='your condition' order by by C.id desc
Hope this can help you!
I think you need to use CONCAT_WS()
There is a nice example of its usage in below link
MySQL SELECT AS combine two columns into one
My table description is as follows
**entry_table**
- serial(int)
- s_name(varchar)
- user_id(int)
- id(int)
**Students_details**
- id(int)
- user_id(int)
- student_name(varchar)
- adress(varchar)
**User_login**
- user_id(int)
- user_name(varchar)
- password(varchar)
- alotment(bool)
Scenario is that the students apply for multiple scholarships. Their selections are stored in the entry_table's s_name, user_id and id fields.
My next step is to build a sorted list of all the students who applied for a particular scholarship eg:"scholarship1".
This list should also show the student's name(student_name field of the students_details table)
The lists are to be sorted according to two types of scholarships that the system offers(merit and need). Applicants of the merit scholarship are required to be sorted in descending order using the ratio(obtained marks/ total marks). However, the need scholarship is to be shorted in ascending order as it uses the ratio(family income/no. of non-earning family members)
I tried to join my tables using
$query = "SELECT *FROM entry_table, students_details
WHERE entry_table.id=students_details.id
group by entry.s_id,entry.student_id";
Please help in the sorting as per type problem. Also the above query helps joining the tables but doesnt achieve the purpose.
thanking you in advance
select * from entry_table inner join students_details on entry_table.id=students_details.id order by entry.student_id asc;
First thing you should connect tables properly.
$query = "SELECT sd.student_name, et.s_name FROM Student_details AS sd LEFT JOIN
entry_table AS et ON et.user_id = sd.user_id LEFT JOIN
user_login AS ul ON ul.user_id = sd.user_id
WHERE et.s_name = 'merit'
ORDER BY et.s_name DESC
UNION ALL
SELECT sd.student_name, et.s_name FROM Student_details AS sd LEFT JOIN
entry_table AS et ON et.user_id = sd.user_id LEFT JOIN
user_login AS ul ON ul.user_id = sd.user_id
WHERE et.s_name = 'need'
ORDER BY et.s_name ASC"
If you need a list you don't need to group, as far as you don't need a count number on any field or unique rows.
This is what I have in the top of my head, maybe do the trick I didn't test it, but maybe give you an idea.
I can't see the ratio field on your tables.
Use Join instead where to connect tables, makes more sense and improve query performance.
Next time, put SQL table code, is more useful to give a better response.
Sorry for my english!!!
I am working in PHP. This is my query:
$sql = "SELECT *
from place as s
where checkDistance($lati1,$longi1,s.lat,s.lon)<$dist";
This place table has three fields: placeId, PlaceName and Address. Now I want to calculate rating of placeId which are the result of above query. To calculate the rating I have another table rating in which there are two fields: placeId and noOfPerson.
Rating will be calculated by (noOfPerson/maximum_no_of_person) for each placeId. How can i implement this?
Your query could do majority of work here, this will select values from place table joined with number of person for each place, ordered by ranking you need, top-bottom:
SELECT s.placeid, s.PlaceName, s.Address, r.noOfPerson
FROM place as s JOIN rating as r ON (s.placeid = r.placeid)
WHERE checkDistance($lati1,$longi1,s.lat,s.lon)
ORDER BY r.noOfPerson / ( SELECT MAX(noOfPerson) FROM rating ) DESC