mySQL - Using two JOINs in one query? - php

I am trying to use two JOIN statements in one query,
$sqlsorgu = mysql_query("SELECT *, COUNT(*), AVG(clicks), AVG(scrolls), AVG(spent)
FROM track where referid='".$memberr."' GROUP BY referer ORDER BY id desc limit 15
JOIN
(
select id, country, num, num*100/total pct
from (SELECT id,country, count(*) as num
FROM track GROUP BY country
ORDER BY num desc limit 5) x
join (select count(*) total from track) y
) tc on t.id = tc.id") or die(mysql_error());
but I am getting this error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'JOIN ( select id, country, num, num*100/total pct from (SELECT id,country' at line 1
What is the correct way to use it ?

GROUP BY/ WHERE/ Order by come after join statements. Try reording like:
"SELECT *, COUNT(*), AVG(clicks), AVG(scrolls), AVG(spent)
FROM track t
JOIN
(
select id, country, num, num*100/total pct
from (SELECT id,country, count(*) as num
FROM track GROUP BY country
ORDER BY num desc limit 5) x
join (select count(*) total from track) y
) tc on t.id = tc.id
where referid='".$memberr."'
GROUP BY referer
ORDER BY tc.id desc limit 15

Related

How to replace Over clause in sql version 4.9.5

I am trying to run a query to find the count and percentage of artisan based on gender. The query is running absolutely fine on the SQL server 8. But not on my live server which is 4.9.5.
The below is my query.
SELECT industry
, count(*) as cnt
, (count(*)*100.0/sum(count(*))over()) as perc
FROM `artisan_work`
GROUP BY industry
ORDER BY cnt DESC
In any database, you should be able to use:
SELECT aw.industry, count(*) as cnt,
count(*) * 100.0 / tot.cnt as perc
FROM artisan_work aw cross join
(SELECT COUNT(*) as cnt FROM artisan_work) tot
GROUP BY aw.industry
ORDER BY cnt DESC
SELECT industry
, count(*) as cnt
, (count(*)*100.0/(select count(*) from artisan_work )) as perc
FROM artisan_work a
GROUP BY industry
ORDER BY cnt DESC

Multiple Counts in MYSQL PHP Query

I'm trying to create a leaderboard but i'm not sure how to do the mysql query.
I would like to count all the levels from a player in the skills table and get the total Level and count all the experience from a player in the experience table and get the Total Exp along with displaying the persons name from the users column.
There is 3 tables factions_mcmmo_users, factions_mcmmo_experience, factions_mcmmo_skills.
This is what i have so far but it doesn't work:
$sql = ("SELECT a.id,
(SELECT COUNT(*) FROM factions_mcmmo_experience WHERE user_id = a.id) as TotalXP,
(SELECT COUNT(*) FROM factions_mcmmo_skills WHERE user_id = a.id) as TotalLevel
FROM (SELECT DISTINCT id FROM factions_mcmmo_users) a LIMIT 10;");
Any help would be very appreciated
EDIT: I have it working now but i'm unsure if its the most efficient way to do things so if anyone could help me out if theres a better way, it would mean a lot.
I would also like to know if it's possible to display the total exp and level with commas if the number is in the thousands for example: total level 5,882 and total xp 582,882
EDIT 2:
I have figured out how to format the numbers but still don't know if my code is efficient
$sql = ("SELECT id, user,
(SELECT FORMAT(Sum(taming)+Sum(mining)+Sum(woodcutting)+Sum(repair)+Sum(unarmed)+Sum(herbalism)+Sum(excavation)+Sum(archery)+Sum(swords)+Sum(axes)+Sum(acrobatics)+Sum(fishing)+Sum(alchemy),0) FROM factions_mcmmo_skills b WHERE b.user_id = a.id) as TotalLevel,
(SELECT FORMAT(Sum(taming)+Sum(mining)+Sum(woodcutting)+Sum(repair)+Sum(unarmed)+Sum(herbalism)+Sum(excavation)+Sum(archery)+Sum(swords)+Sum(axes)+Sum(acrobatics)+Sum(fishing)+Sum(alchemy),0) FROM factions_mcmmo_experience c WHERE c.user_id = a.id) as TotalXP
FROM (SELECT id, user FROM factions_mcmmo_users) a group by id ORDER BY TotalLevel DESC, TotalXP DESC LIMIT 10;");
EDIT 3
Updated code from scaisEdge but was displaying everyones level as 1 and XP as 1, so i changed count(*) changed to sum, added an order By TotalLevel in Descending order and that seems to have worked but i can't get it to display the persons name (user column) in the user table? not sure if i was supposed to change to sum because it didn't work the other way.
$sql = ("SELECT a.id, b.TotalXP, c.TotalLevel
FROM (SELECT DISTINCT id FROM factions_mcmmo_users) a
INNER JOIN (
SELECT user_id, Sum(taming)+Sum(mining)+Sum(woodcutting)+Sum(repair)+Sum(unarmed)+Sum(herbalism)+Sum(excavation)+Sum(archery)+Sum(swords)+Sum(axes)+Sum(acrobatics)+Sum(fishing)+Sum(alchemy) as TotalXP
FROM factions_mcmmo_experience
GROUP By user_id
) b on b.user_id = a.id
INNER JOIN (
SELECT user_id, Sum(taming)+Sum(mining)+Sum(woodcutting)+Sum(repair)+Sum(unarmed)+Sum(herbalism)+Sum(excavation)+Sum(archery)+Sum(swords)+Sum(axes)+Sum(acrobatics)+Sum(fishing)+Sum(alchemy) as TotalLevel
FROM factions_mcmmo_skills
GROUP by user_id
) c on c.user_id = a.id
ORDER BY TotalLevel DESC
LIMIT 10;");
EDIT 4
Everything working but when i try to format the totals using "FORMAT(Sum(Columns), 0) on the inner joins, the EXP Total appears to work but the main Total Level is not displaying results that are over 1,000 and it breaks the leaderboard positioning, it should be sorting them on total level but it appears to be random, when u remove the format,0 it goes back to working
I would like it to display commas if the number number is the thousands for example: Total Level: 5,532 and Total EXP 5882,882
See live demo: http://mcbuffalo.com/playground/leaderboards/server/factions-mcmmo.php
Updated Code trying to use Format:
$sql = ("SELECT a.id, a.user, b.TotalXP, c.TotalLevel
FROM (SELECT id, user FROM factions_mcmmo_users) a
INNER JOIN (
SELECT user_id, FORMAT(Sum(taming)+Sum(mining)+Sum(woodcutting)+Sum(repair)+Sum(unarmed)+Sum(herbalism)+Sum(excavation)+Sum(archery)+Sum(swords)+Sum(axes)+Sum(acrobatics)+Sum(fishing)+Sum(alchemy), 0) as TotalXP
FROM factions_mcmmo_experience
GROUP By user_id
) b on b.user_id = a.id
INNER JOIN (
SELECT user_id, FORMAT(Sum(taming)+Sum(mining)+Sum(woodcutting)+Sum(repair)+Sum(unarmed)+Sum(herbalism)+Sum(excavation)+Sum(archery)+Sum(swords)+Sum(axes)+Sum(acrobatics)+Sum(fishing)+Sum(alchemy), 0) as TotalLevel
FROM factions_mcmmo_skills
GROUP by user_id
) c on c.user_id = a.id
ORDER BY TotalLevel DESC;");
EDIT 5
Changed number with PHP, everything works
Original Images
you could use an couple of inner join
$sql = ("SELECT a.id, a.name, b.TotalXP, c.TotalLevel
FROM (SELECT DISTINCT id, name FROM factions_mcmmo_users) a
INNER JOIN (
SELECT user_id, COUNT(*) as TotalXP
FROM factions_mcmmo_experience
GROUP By user_id
) b on b.user_id = a.id
INNER JOIN (
SELECT user_id, COUNT(*) as TotalLevel
FROM factions_mcmmo_skills
GROUP by user_id
) c on c.user_id = a.id
LIMIT 10

MYSQL - Get User and Most Recent Purchase Data

I am trying to do a MYSQL query where I get the most recent purchase for a user and then see if falls within certain criteria. Here is the query I put together:
select
users_purch.purch_date as purchase_date,
users_purch.total_amount as purchase_amount,
users.*
from
users
left join
(
select
max(date) as purch_date,
user_id,
total_amount
from
users_purchases
group by
user_id
) as users_purch
on users_purch.user_id = users.id
where
users_purch.purch_date < '2016-11-01'
and users_purch.total_cost < 112.49
order by
users_purch.purch_date desc
It seems that the query works but fails in certain aspects. For example, if a user has more than one purchase entry it is getting the max date but the amount as total_cost that the query retrieves is not from the same row as the max date. How can I rewrite this query to give me the most recent purchase record in its entirety?
Thanks!
You have to join once more to user_purchases table in order to get the information about the date:
select
users_purch.purch_date as purchase_date,
users_purch.total_amount as purchase_amount,
users.*
from
users
left join
(
select
max(date) as purch_date,
user_id
from
users_purchases
group by
user_id
) as users_purch
on users_purch.user_id = users.id
left join
(
select
user_id,
date,
total_amount
from
users_purchases
) as users_purch2 on users_purch.user_id = users_purch2.user_id and
users_purch2.date = users_purch.purch_date
where
users_purch.purch_date < '2016-11-01'
and users_purch.total_cost < 112.49
order by
users_purch.purch_date desc
due the group by you have in this select
if you need the amount of the max(date) rewrite extecting the proper amount
select
users_purch.purch_date as purchase_date,
users_purch.total_amount as purchase_amount,
users.*
from
users
left join
(
select t1.purch_date, t1.user_id, t2.total_amount from (
select
max(date) as purch_date,
user_id
from users_purchases
group by user_id ) t1
inner join (
date,
user_id,
total_amount
from users_purchases
) t2 on t1.user_id= t2.user_id, t1.purch_date = t2.date
) as users_purch
on users_purch.user_id = users.id
where
users_purch.purch_date < '2016-11-01'
and users_purch.total_cost < 112.49
order by
users_purch.purch_date desc
You can try this one, mate:
SELECT
up.date AS 'purchase_date',
up.total_amount AS 'purchase_amount',
u.*
FROM
users u
INNER JOIN users_purchases up ON up.user_id = u.user_id
INNER JOIN (
# get max date per user_id
SELECT user_id, max(date) AS 'purch_date'
FROM users_purchases
GROUP BY user_id
) max_up ON
max_up.user_id
# join that date to get the correct total_amount
AND max_up.`purch_date` = up.`date`
WHERE
up.`date` < '2016-11-01'
AND up.total_amount < 112.49
GROUP BY u.user_id
ORDER BY up.`date` DESC;
Note
Max Date per user_id
Value of total_amount per Max Date
Grouped per user_id
Ordered descending using users_purchases.date

Resolve Mysql query to Select unique from id and order by date acceding

Im new to msql! Can any one re-correct me
My table name = details, column = id, name, mobile, email, city, state, Pincode, difftime
I need to retrieve data unique by ID,
get count on Id retrieve on desc order
difftime(Datetime) in Asc order
Please help me on this,
select * from details
where id s
join (SELECT id FROM `details`
group by id
ORDER BY `difftime` ASC,count(id) desc) d
on d.id=s.id
ORDER BY s.`difftime`
LIMIT 5
select D2.*, D1.* from details D1
left outer join (SELECT D.id, count(*) as total_ids FROM `details` D
group by D.id
) D2
on D1.id=D2.id
ORDER BY D1.`difftime` ASC, D2.total_ids desc
LIMIT 5

How break ties after getting rank

I have a query that gets me a users rank in a table of scores.
SELECT
*
FROM
(SELECT
*, #rank:=#rank + 1 rank
FROM
(SELECT
user_id, SUM(round_total) TotalPoints
FROM
sx14sp_mem_picks
GROUP BY user_id) s, (SELECT #rank:=0) init
ORDER BY TotalPoints DESC) r
WHERE
user_id = 22234
There is a problem with ties. I have a table field "pick_date" that i would like to use to break ties with. The user who made his picks first beats the tie.
Any ideas?
If sx14sp_mem_picks.pickdate is the field to break ties then in the order by sx14sp_mem_picks subquery, add
min( pickdate) asc
This will put the earliest pickdate first - you have to use MIN() bc you need to use an aggregate function given the use of "group by".
You need to order by the pick date in addition to the total points. However, you are talking about multiple rows per user. So, let's take the last pick date:
SELECT *
FROM (SELECT *, (#rank:=#rank + 1) as rank
FROM (SELECT user_id, SUM(round_total) as TotalPoints, max(pick_date) as max_pick_date
FROM sx14sp_mem_picks
GROUP BY user_id
) s CROSS JOIN
(SELECT #rank := 0) init
ORDER BY TotalPoints DESC, max_pick_date asc
) r
WHERE user_id = 22234;

Categories