sql avg usage causing illegal ordering of resultset - php

Here is my SQL
SELECT DISTINCT(scl_reviews.locid),avg(scl_reviews.rating)
AS average,scl_locations.name,scl_locations.phone,scl_locations.address,
scl_location.city,scl_locations.state,scl_locations.zip
FROM scl_reviews
LEFT JOIN scl_locations ON scl_locations.locid = scl_reviews.locid
GROUP BY scl_reviews.locid ORDER BY average DESC LIMIT 100
What this means is that it will grab locations with the highest rating and sort them by the average.
The problem is that the records with an average of 5 seem to query their positions differently. Sometimes my record with an id of 3115 is position 1 and sometimes its position 3.
Not quite sure whats going on,. I assume it has to do with my query.

ORDER BY average DESC leaves undetermined how the order will be when there are equal values. So just list a unique column in the sort order. You might like the column number short-cut:
ORDER BY 2 DESC, 1 DESC

Add a secondary order. This kicks in when your first order has equal values.
Check the new order by clause:
SELECT DISTINCT(scl_reviews.locid),avg(scl_reviews.rating)
AS average,scl_locations.name,scl_locations.phone,scl_locations.address,
scl_location.city,scl_locations.state,scl_locations.zip
FROM scl_reviews
LEFT JOIN scl_locations ON scl_locations.locid = scl_reviews.locid
GROUP BY scl_reviews.locid
ORDER BY average DESC, scl_reviews.locid DESC LIMIT 100

Related

how to select mysql two colume take last 200 id order desc, then get 5 order by counter desc for best performace

my table keep million records.
i just want to extract the 5 most counter rows in last 200 rows.
Im using this but as i thinking this is two time select .. that may not right for best performace plase advice.
"select * from (
select sid,title,catid,counter from table_stories
where catid=1 order by sid desc limit 200
) astemps order by counter desc limit 5"
thanks very much..
regards
This is your query:
select *
from (select sid, title, catid, counter
from table_stories
where catid = 1
order by sid desc
limit 200
) astemps
order by counter desc
limit 5;
For optimal performance, you want an index on table_stories(catid, sid desc). You can throw title and counter into the index, but they won't help much. Unfortunately, MySQL may not take advantage of the descending key for to replace the sort.

ORDER BY with two columns

I have two tables in the mysql database:
trips(id,name,desc,createdat)
trip_ratings(id,ratingvalue,tripid,userid)
I want to get 100 most recent trips sorted by higher average ratings.
I have tried following mysql query:
SELECT AVG(ratingvalue),tripid,tripcreatedat FROM trip_ratings
INNER JOIN trips on trip_ratings.tripid = trips.id
GROUP BY trip_ratings.tripid
ORDER BY AVG(ratingvalue) DESC, tripcreatedat DESC
LIMIT 100
But as it sorts by rating value first I only get trips sorted by higher ratings.
Is it possible within a single query? can anyone hint me what should I do?
EDIT: example:
I have data in trip_ratings table like this:
and from my tried query I can get results like this.
But my problem is: Get 100 most recent trips sorted by higher average ratings.
Instead of downvoting and close votes, can anyone have any solution for that or can anyone give me a hint that is it possible within a single query? thanks.
One option is to use an inline view, to first get the "100 most recent trips".
Then join that to trip_ratings, to calculate the "average rating" and order by that result.
SELECT m.id AS tripid
, AVG(r.ratingvalue) AS average_rating
, m.tripcreatedat
FROM ( SELECT t.id
, t.tripcreatedat
FROM trips t
ORDER BY t.tripcreatedat DESC
LIMIT 100
) m
LEFT
JOIN trip_ratings r
ON r.tripid = m.id
GROUP BY m.id, m.tripcreatedat
ORDER BY AVG(r.ratingvalue) DESC
If there are multiple trips that have the same average rating, it's indeterminiate what order those will be returned in. You can add other expressions to the order by to make it more deterministic.
ORDER BY AVG(r.ratingvalue) DESC, m.tripcreatedat DESC, m.id DESC
This isn't the only way to do it. There are other approaches that will achieve an equivalent result.

Select from last ID and older than it by 25 [MySQL]

I have posts which has fields (ID,title,date) What I'm looking for it to select rows order by date desc just limit for 25 records
lets say if we run that one it will show the last row with ID (600) like this:
(600,601,602,.....,625)
so I want after that to select another 25 records but min(id) before the last one (600) so it will be like this
(575,576,577,.....,599)
For example consider that the first result gives the descending last five IDs.
SELECT idprocess FROM process ORDER BY idprocess DESC LIMIT 5
248034
248033
248032
248031
248030
You could use a SELECT into a temporary table to mess with your result set's ORDER BY and LIMIT. The sub-query LIMIT should be the sum of the records you want back and how many you want skipped off the end.
SELECT t1.idprocess FROM
(SELECT idprocess FROM process ORDER BY idprocess DESC LIMIT 10) AS t1
ORDER BY idprocess ASC LIMIT 5
248025
248026
248027
248028
248029

Retrieve the top 10 from the database

I have this query but I just want to return the top 10 based on the num_guess. I don't know the format of the query. I don't know where to put LIMIT or TOP. Please help!
"SELECT user,num_guess FROM game JOIN difficulty USING (difficulty_no) WHERE difficulty_no=2 ORDER BY num_guess ASC "
use limit 10
something like this
"SELECT user,num_guess FROM game
JOIN difficulty USING (difficulty_no)
WHERE difficulty_no=2 ORDER BY num_guess ASC limit 10"
With two arguments, the first argument specifies the offset of the first row to return, and the second specifies the maximum number of rows to return. The offset of the initial row is 0 (not 1):
-- SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
SELECT user,num_guess FROM game
JOIN difficulty USING (difficulty_no)
WHERE difficulty_no=2 ORDER BY num_guess ASC limit 0, 10
you can go with LIMIT 10 here in this context
Just add LIMIT 10 at the end of your query.
use LIMIT 10
"SELECT user,num_guess FROM game
JOIN difficulty USING (difficulty_no)
WHERE difficulty_no=2 ORDER BY num_guess ASC LIMIT 10"
for more information check this http://dev.mysql.com/doc/refman/5.5/en//limit-optimization.html
Yes the limit would work here.
SELECT user,num_guess FROM game
JOIN difficulty USING (difficulty_no)
WHERE difficulty_no=2 ORDER BY num_guess ASC LIMIT 10;
To view more just increase the limit.

MySQL grouping by day then display the date from the grouped results

So i have a whole load of votes going into a voting system. I want to display how many votes i have in any one day. But i also want to then, display the amount of votes per day and spit out which day they were voted on, i.e 24k votes on 05/06/12, 27k votes on 06/06/12
SELECT count(*) AS count
FROM results
GROUP BY DAY(datesubmitted), YEAR(datesubmitted), MONTH(datesubmitted)
ORDER BY DAY(datesubmitted) DESC, YEAR(datesubmitted) DESC, MONTH(datesubmitted) DESC
Is my query, i tried to add something like
DAY(FROM_UNIXTIME(datesubmitted)) as order_day
but this just throws a null which i found interesting as i'd expect the query to fail as there aren't any outers.
Why don't you simply GROUP BY datesubmitted DESC? Also, no need to ORDER BY if it's following the same criteria as GROUP BY.
Number of votes on a specific day:
SELECT COUNT(*) AS total
FROM results
WHERE datesubmitted BETWEEN #dateMin AND #dateMax
Number of votes for each separate day:
SELECT COUNT(*) AS total, DATE(datesubmitted) AS day
FROM results
GROUP BY DATE(datesubmitted)
ORDER BY DATE(datesubmitted) DESC
UPDATED AGAIN
So just saw a new answer but for me how i got it working was:
SELECT count(*) AS count, DAY(datesubmitted) AS newday,
YEAR(datesubmitted) as newyear ,MONTH(datesubmitted) as newmonth
FROM results
GROUP BY DAY(datesubmitted), YEAR(datesubmitted), MONTH(datesubmitted)
ORDER BY YEAR(datesubmitted) DESC, MONTH(datesubmitted) DESC, DAY(datesubmitted) DESC
This way i get the correct ordering with year, month and day properly and also it displays the dates. I could concat them, but thats for another day.

Categories