how would I combine these two queries? - php

This is my existing query:
$query = mysql_query("SELECT s.*,
UNIX_TIMESTAMP(`date`) AS `date`,
f.userid as favoritehash FROM songs s
LEFT JOIN favorites f ON f.favorite = s.id AND f.userid = '$userhash'
ORDER BY s.date DESC");
It gathers all my songs and the associated favorite information from my db.
This is a basic pagination query that returns values from my db by groups of days:
$query = mysql_query("
select * from songs t1 join (
select to_days(date) day from songs
group by day
order by day desc
limit $start_row, $items_per_page
) t2
on to_days(t1.date) = t2.day
order by day desc") or die(mysql_error());
Here is the column info for the two tables songs and favorites
Songs:
Favorites:
The correlation between favorites and songs is pretty simple where the favorite value in favorites holds the unique id of the song it is a favorite of.
My question is how would I combine these two queries so as to return all the information in the original query but grouped and paginated as it is in the second query?

SELECT B.*
FROM favorites as A
JOIN (
select * from songs t1 join (
select to_days(date) day from songs
group by day
order by day desc
limit $start_row, $items_per_page
) t2
on to_days(t1.date) = t2.day
order by day desc
) as B
ON A.Favorite = B.ID
ORDER BY B.DAY, B.ID

I don't use MySQL and not familiar with using the "limit", but this script might work. The LEFT JOIN with favorites should not increase the row count and append the columns. Would the "limit" work on the outer script also?
select s.*,UNIX_TIMESTAMP(`date`) AS `date`, f.userid as favoritehash
from songs s
join (
select to_days(date) day
from songs
group by to_days(date)
order by day desc
limit $start_row, $items_per_page
) s2 on to_days(s.date) = s2.day
LEFT JOIN favorites f ON f.favorite = s.id AND f.userid = '$userhash'

Related

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...

How to get the latest record by date and not the first from a table?

In my query i get the first record i olje table when i group by frl_nr. There are many records with the same frl_nr i the olje table. I want to get the latest record from the olje table by date column. Her is my search string:
$sql = "SELECT *
FROM frl_sok
INNER JOIN olje ON frl_sok.id_nr = olje.id_nr
WHERE frl_sok.kunde_nr = '$kunde'
AND frl_sok.jobb_nr = '$jobb_nr'
GROUP BY frl_sok.frl_nr DESC";
What is the solution?
Both of my tables are here
You should use row_number() rather than trying to group by.
Try this:
select * from (
SELECT *,
row_number() over (partion by frl_sok.frl_nr order by date desc) rn
FROM frl_sok
INNER JOIN olje ON frl_sok.id_nr = olje.id_nr
WHERE frl_sok.kunde_nr = '$kunde'
AND frl_sok.jobb_nr = '$jobb_nr'
) q where rn=1"
Here is the solution I came up with and it works.
$sql = "SELECT a.id_nr, a.frl_nr, a.maskin_id, a.tilstand_olje, b.date FROM frl_sok a INNER JOIN olje b ON a.id_nr = b.id_nr INNER JOIN (SELECT id_nr, MAX(date) Max_Date FROM olje GROUP BY id_nr) c ON b.id_nr = c.id_nr AND b.date = c.Max_date WHERE a.kunde_nr = '$kunde' AND a.jobb_nr = '$jobb_nr'";

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 query order the results in GROUP BY 3 Tables Count

I'm coding a listing system and I'm trying to get the posts ORDER by number of comments and votes FROM 2 tables.
Table1 : Lists => id, title, detail
Table2 : Votes => voteid, listid
Table3 : Comments => commentid, listid
WHERE MY Current query is
$q = mysql_query("SELECT * FROM zoo_leads
LEFT JOIN Votes ON Lists.id=Votes.listid
LEFT JOIN Comments ON Lists.id=Comments.listid
GROUP BY Lists.id ORDER BY Comments.listid DESC LIMIT 10
it is showing me results perfectly but ORDER BY is Lists.id Instead of number of votes and comments
Try:
SELECT *
FROM zoo_leads
LEFT JOIN votes
ON lists.id = votes.listid
LEFT JOIN comments
ON lists.id = comments.listid
GROUP BY lists.id
ORDER BY COUNT(votes.id) DESC,
COUNT(comments.id) DESC
LIMIT 10
That is because you have ORDER BY Comments.listid in your SQL statement.

adding DATE_SUB to query to return range of values in mysql

Here is my original query:
$query = mysql_query("SELECT s.*, UNIX_TIMESTAMP(`date`) AS `date`, f.userid as favoritehash FROM songs s LEFT JOIN favorites f ON f.favorite = s.id AND f.userid = '$userhash' ORDER BY s.date DESC");
This returns all the songs in my DB and then joins data from my favorites table so I can display wich items a return visitors has clicked as favorites or not. Visitors are recognized by a unique has storred in a cookie and in the favorites table.
I need to alter this query so that I can get just the last months worth of songs. Below is my attempt at adding DATE_SUB to my query:
$query = mysql_query("SELECT s.*, UNIX_TIMESTAMP(`date`) AS `date`, f.userid as favoritehash FROM songs s WHERE `date` >= DATE_SUB( NOW( ) , INTERVAL 1 MONTH ) LEFT JOIN favorites f ON f.favorite = s.id AND f.userid = '$userhash' ORDER BY s.date DESC");
Suggestions?
You just have to move the WHERE clause:
SELECT
s.*,
UNIX_TIMESTAMP(`date`) AS `date`,
f.userid as favoritehash
FROM
songs s
LEFT JOIN favorites f ON f.favorite = s.id AND f.userid = '$userhash'
WHERE `date` >= DATE_SUB( NOW( ) , INTERVAL 1 MONTH )
ORDER BY s.date DESC
LEFT JOIN is a part of the list of tables in FROM, you can't have conditions where.

Categories