How can i retrieve data from a table? - php

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

Related

mysql - group results by id and print

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());

Best average rating

I have created a simple rating system for news articles. The news articles are stored in the database table called 'articles'. Each article has a unique id, starting from 1.
So I have 2 articles, ID 1 and ID 2.
I also have a table called 'ratings' that takes the users unique ID, the article ID and the rating that the user gave.
If I give an article with ID 2 a 5/5 star rating, it goes into the 'ratings' table, with article ID 2, my user ID and the rating of 5.
I have figured out how to display the average rating of each article, but I would like to find out how to show the BEST average rating of articles in descending order. Is that at all possible? How could this be done?
Here is how I find the average:
<?
$votesForThis = 0;
$sql = "SELECT * FROM ratings WHERE articleID = ".$articleID." ORDER BY id ASC";
// Check if there are results
if ($result = mysqli_query($con, $sql)) {
// Loop through each row in the result set
while($row = mysqli_fetch_assoc($result)) {
$votesForThis++;
}
}
$result = mysqli_query($con, 'SELECT SUM(vote) AS vote_sum FROM ratings WHERE articleID=' . $articleID);
$row = mysqli_fetch_assoc($result);
$voteSum = $row['vote_sum'];
$averageVotes = $voteSum / $votesForThis;
?>
MySQL has an avg function you can use instead of implementing this logic yourself. From there, it's just a matter of grouping by the article ID and ordering by the average:
SELECT articleID, AVG(vote)
FROM ratings
GROUP BY articleID
ORDER BY 2 DESC
The best practice for doing this is to add a new column to your article table called average_rating and update it with a cron job or after every voting.
Keep in mind that after a while your rating table will become giant and calculating average rating on every page refresh will put huge load on your server.
I would use de-normalization in this one.
I would use triggers to update a previously created column on table articles which would store it's average rating.
I would have posted an example of trigger but you haven't posted which database are you using.
Mysql: https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html
Postgresql: https://www.postgresql.org/docs/9.1/sql-createtrigger.html
Each time a rating it's done, updated or deleted a trigger would update this column with it's current average using the built-in avg function.
At the end you'll only have to create a select on the articles table ordered by this rating column desc.
And create an index on this average rating column to have even faster results.
SELECT articleID, AVG(vote)
FROM ratings
GROUP BY articleID,vote
ORDER BY DESC
used this Query

What join to use

I have two tables, one for registered users and one to store votes.
We are logging in with registrants.id and registrants.zipcode. Once they vote their votes are inserted into the votes table, along with their Registration ID.
Im trying to right a select statement that returns a record that will select all the records for Matched ID and Zipcode, but the ID is not in the Votes.voter column. i have tried all kinds of variations of all the joins i can think of. is it something simple i am missing.
SELECT * FROM registrants
LEFT JOIN votes on registrants.id = votes.voter
WHERE registrants.id = 1 AND registrants.zipcode = 46706 and votes.voter <> 1
Perhaps a not exists query:
select * from registrants
where registrants.zipcode = '46706'
and not exists (select 1 from votes where registrants.id = votes.voter)

Select statement to display the result with combination of 2 columns

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

Join a table only where there is a count in the subquery

I'm making a search engine in which a page visitor can search for music artists based on 4 different attributes which the artists will have a rating of from 0- 100 and by entering the minimum value of a specified attribute, the visitor can view the list of artists with ratings greater than or equal to the desired value. After the query I have the fetch array and foreach statement already set but I am having trouble with the query.
I've tried the following query statement. It's one cohesive statement:
SELECT users.username, databaseimage.profile
// users.username is artists username
// databaseimage is table where profile pic is stored
FROM users
JOIN databaseimage ON users.id = databaseimage.user_id
JOIN attributes ON users.id = attributes.userid
// user.id, database.user_id, and attribute.userid all correspond to the id of a specified artist
// attributes is table where attributes are stored
The above gets me all the data that I need. Below is the part I need help with. I want to narrow the data down such that only the data corresponding to artists with attribute ratings (as attr) greater than $selectnumber (Number specified by the visitor) is in the the result array. This what I have tried.
WHERE attribute.userid
HAVING COUNT() IN (
SELECT userid, ($attribute DIV TotalRatingEntries) as attr
FROM attributes
WHERE attr >= '$selectnumber'
)
A far as I understand data structure I can propose the query below:
SELECT
users.username,
databaseimage.profile
FROM
users
JOIN databaseimage ON users.id = databaseimage.user_id
JOIN attributes ON users.id = attributes.userid
WHERE
attribute.userid IN
(
SELECT
userid
FROM
attributes
group by
userid,TotalRatingEntries
having
sum(attribute)/TotalRatingEntries >= '$selectnumber'
)
Please provide more details about these 3 tables, maybe I misunderstood something.

Categories