Reference 'r1' not supported (reference to group function) - php

can me anyone help? i want to order users by total rating DESC, 2 ratings are in different tables , my sql:
SELECT dle_users.user_id, dle_users.user_group, dle_users.name,
dle_users.foto,
SUM(dle_comments.rating) as r1,
SUM(dle_post_extras.rating) as r2
FROM dle_users
JOIN dle_comments
ON dle_comments.user_id = dle_users.user_id
JOIN dle_post_extras ON dle_post_extras.user_id = dle_users.user_id
WHERE dle_comments.rating
AND dle_post_extras.rating > 0
GROUP BY dle_users.user_id
ORDER BY SUM(r1+r2) DESC
LIMIT 0,10

Aggregate before joining or your sums will be off:
SELECT u.user_id, u.user_group, u.name, u.foto,
COALESCE(c.r1, 0) as r1, COALESCE(e.r2, 0) as r2
FROM dle_users u LEFT JOIN
(SELECT user_id, SUM(rating) as r1
FROM dle_comments
GROUP BY user_id
) c
ON c.user_id = u.user_id LEFT JOIN
(SELECT user_id, SUM(rating) as r2
FROM dle_post_extras
WHERE rating > 0
GROUP BY user_id
) e
ON e.user_id = u.user_id
GROUP BY dle_users.user_id
ORDER BY COALESCE(r1, 0) + COALESCE(r2, 0) DESC
LIMIT 0, 10

Related

mysql left outer join ranking

I'm trying to rank with the left outer join
My sql is :
SET #rank=0;
SELECT #rank:=#rank+1 AS rank, h.name, COUNT(v.hId) AS votes
FROM users h LEFT OUTER JOIN users_votes v ON h.id = v.hId GROUP BY h.id
ORDER BY rank ASC
;
The right thing would be to return like this
rank | name | votes
1 Luck 4
2 Marc 3
3 Santos 2
4 Matheus 0
But it's returning the wrong way:
rank | name | votes
1 Santos 2
2 Marc 3
3 Luck 4
4 Matheus 0
You are ordering in ASC way, change it to DESC. Like this:
SET #rank=0;
SELECT #rank:=#rank+1 AS rank, h.name, COUNT(v.hId) AS votes
FROM users h LEFT OUTER JOIN users_votes v ON h.id = v.hId GROUP BY h.id
ORDER BY rank DESC
;
In MySQL 8+, you should use row_number():
SELECT ROW_NUMBER() OVER (ORDER BY COUNT(*) DESC) as rank,
h.name, COUNT(*) AS votes
FROM users h LEFT OUTER JOIN
users_votes v
ON h.id = v.hId
GROUP BY h.id
ORDER BY rank ASC;
Variables are deprecated in 8+.
In earlier version, you can use variables, but they tend not to respect ORDER BY or GROUP BY. So, with those constructs, you need a subquery:
SELECT (#rn := #rn + 1) as rank, hv.*
FROM (SELECT h.name, COUNT(*) AS votes
FROM users h LEFT OUTER JOIN
users_votes v
ON h.id = v.hId
GROUP BY h.id
ORDER BY rank ASC
) hv CROSS JOIN
(SELECT #rn := 0) params;
Doesn't works, the rank number is wrong. I want to sort by votes and rank the most voted

LIMIT LEFT join to last updated row from multiple rows

This is my code i am trying to left join the latest team data, not every piece of data. i have tried just using limit 1 but doesnt return anything
ORDER BY updated DESC LIMIT 1
this doesnt work
Any ideas?
$sql = "SELECT
events.id, events.time,events.status, events.home_team,events.away_team,events.league,
ht.id as home_id,ht.name as home_name,at.name as away_name,
statistics.home_goals,statistics.away_goals,statistics.time as game_time,
leagues.id as league_id,leagues.name as league_name,leagues.type as league_type,
country.name as country_name,country.logo,
hts.home_scored, ats.away_scored,
hts.home_conceeded,ats.away_conceeded,
hts.home_win,ats.away_win,
hts.home_15,ats.away_15,
hts.home_25,ats.away_25,
hts.home_btts, ats.away_btts,
hts.home_fts, ats.away_fts,
hts.home_cs, ats.away_cs,
hts.home_corners_for, ats.away_corners_for,
hts.home_corners_against, ats.away_corners_against,
hts.home_cards, ats.away_cards
FROM events
LEFT JOIN teams ht
ON ht.id = events.home_team
LEFT JOIN teams at
ON at.id = events.away_team
LEFT JOIN leagues
ON leagues.id = events.league
LEFT JOIN country
ON country.id=leagues.country
LEFT JOIN ( SELECT team,home_scored,home_conceeded,home_win,home_15,home_25,home_btts,home_fts,home_cs,home_corners_for,home_corners_against,home_cards FROM team_quick_stats ORDER BY updated DESC) hts
ON ht.id=hts.team
LEFT JOIN ( SELECT team,away_scored,away_conceeded,away_win,away_15,away_25,away_btts,away_fts,away_cs,away_corners_for,away_corners_against,away_cards FROM team_quick_stats ORDER BY updated DESC) ats
ON at.id=ats.team
LEFT JOIN statistics
ON statistics.event_id=events.id
WHERE (events.time BETWEEN $start AND $end) ORDER BY country.list_order, leagues.country ASC , leagues.id ASC, events.time ASC, home_name ASC";
Here's one way. Replace LEFT JOIN (SELECT team... etc....) ats with...
LEFT
JOIN
( SELECT x.team
, x.etc...
FROM team_quick_stats x
JOIN
( SELECT team
, MAX(updated) updated
FROM team_quick_stats
GROUP
BY team
) y
ON y.team = x.team
AND y.updated = x.updated
) ats...

which is the best way to order by count from multiple tables?

I'm wondering about these queries and I got a work that want to list all users in table user and count for their post photo and video. and can choose to view in sort by these count limit by ASC or DESC.
I've tried them both but see that sub-query is fast than join. i want to know the different between these queries. Why sometimes join is slower that a sub-query. is join best for only two tables? Is this both best for my work? or you can suggest another better solution.
SUB-QUERY
select
user.*,
(select count(*) from post where post.userid = user.id) postCount,
(select count(*) from photo where photo.userid = user.id) photoCount,
(select count(*) from video where video.userid = user.id) videoCount
from user order by postCOunt desc limit $starrow 20
JOIN
SELECT u.id,
COUNT(DISTINCT p.id) AS postCount,
COUNT(DISTINCT ph.id) AS photoCount,
COUNT(DISTINCT v.id) AS videoCount
FROM user u
LEFT JOIN post p
ON p.userid = u.id
LEFT JOIN photo ph
ON ph.userid = u.id
LEFT JOIN video v
ON v.userid = u.id
GROUP BY u.id
ORDER BY postCount LIMIT $startrow 20
Example in HTML page that order by postCount DESC and have paging.
userid postCount photoCount videCount
1 34 5 4
2 30 12 2
3 21 5 6
4 15 8 4
5 12 15 9
6 8 3 10
.. .. .. ..
You can try it this way with JOIN
SELECT u.id, postCount, photoCount, videoCount
FROM user u LEFT JOIN
(
SELECT userid, COUNT(*) postCount
FROM post
GROUP BY userid
) p ON p.userid = u.id LEFT JOIN
(
SELECT userid, COUNT(*) photoCount
FROM photo
GROUP BY userid
) ph ON ph.userid = u.id LEFT JOIN
(
SELECT userid, COUNT(*) videoCount
FROM video
GROUP BY userid
) v ON v.userid = u.id
ORDER BY postCount
LIMIT $startrow, 20

SUM of a secondSELECT statement - PHP - MySQL

I have the following query which works... but I need some changes:
SELECT
p.pid,
p.name,
GROUP_CONCAT( gC.leaguepoints ORDER BY leaguepoints DESC ) AS leaguepoints
FROM
golf_player p
LEFT JOIN
golf_card gC ON
p.pid = gC.pid
GROUP BY
p.pid
ORDER BY
p.name
DESC
What I really want is another property returned called totalleaguepoints which is a SUM of the most recent 20 league points in my table.
How do I add a limit to a group_concat?
It might be something like this?
SELECT
p.pid,
p.name,
GROUP_CONCAT( gC.leaguepoints ORDER BY leaguepoints DESC ) AS leaguepoints,
SUM(
SELECT
gC2.leaguepoints
FROM
golf_card gC2
WHERE
gC2.pid = p.pid
ORDER BY
leaguepoints
DESC
LIMIT 20
) AS totalleaguepoints
FROM
golf_player p
LEFT JOIN
golf_card gC ON
p.pid = gC.pid
GROUP BY
p.pid
ORDER BY
p.name
DESC
P.S, the above query does not run
Do you want just the top 20 league points for each player in the group_concat as well as the sum?
If so maybe use user variables:-
SELECT
p.pid,
p.name,
GROUP_CONCAT( gC.leaguepoints ORDER BY leaguepoints DESC ) AS leaguepoints,
SUM(gC.leaguepoints) AS totalleaguepoints
FROM golf_player p
LEFT JOIN
(
SELECT pid, leaguepoints, #Sequence:=IF(#PrevPid = pid, #Sequence + 1, 0) AS aSequence, #PrevPid := pid
FROM
(
SELECT pid, leaguepoints
FROM golf_card
ORDER BY pid, leaguepoints DESC
) Sub1
CROSS JOIN (SELECT #PrevPid := 0, #Sequence := 0) Sub2
) gC
ON p.pid = gC.pid AND aSequence < 20
GROUP BY p.pid
ORDER BY p.name DESC

How to specify WHERE in a JOIN statement?

This is my first attempt at a JOIN MySQL statement...
I have 2 tables..games and games_ratings
both tables have an id column. the id represents the id of the game. and i only want to get the average of the ints in the rating column where the id in games_ratings is equal to the id from the games table.
SELECT a.id, a.name, AVG(b.rating) AS average FROM games a LEFT JOIN games_ratings b GROUP BY a.id ORDER BY average DESC LIMIT 50;
any ideas?
Try this:
SELECT a.id, a.name, AVG(b.rating) AS average
FROM games a
LEFT JOIN games_ratings b
ON a.id = b.id # <-- You need this line I believe
GROUP BY a.id
ORDER BY average DESC LIMIT 50;
Edit: This is a bit hard without your complete schema, but you can try something like this.
SELECT a.id, a.name, AVG(b.rating) AS average, COUNT( b.id) as votes
FROM games a
LEFT JOIN games_ratings b
ON a.id = b.id
GROUP BY a.id
ORDER BY votes DESC, average DESC LIMIT 50; # <-- You may need to modify this line
Don't forget the WHERE clause he asked for:
where the id in games_ratings is equal to the id from the games table
> SELECT a.id, a.name, AVG(b.rating) AS average
> FROM games a
> LEFT JOIN games_ratings b
> ON a.id = b.id # <-- You need this line I believe
> **WHERE a.id = b.id**
> GROUP BY a.id
> ORDER BY average DESC LIMIT 50;

Categories