i need select some data from two tables ,
please help me use inner join for this selection .
players in selction2 must not be in selection1...
first select :
$rs = "SELECT *
FROM `player`
WHERE `status`=1 AND `credit`>=1 AND `username` NOT LIKE '$user'
ORDER BY ls ASC,credit DESC
LIMIT 0 ,10;
Second: this players must remove from result of selection1
$rs2 = "SELECT *
FROM `ip_log`
WHERE `playerid`='$ui' AND `win`='1' AND `date`='$date' ";`
You can use LEFT JOIN for this:
This shows the log messages for everyone not in selection 1.
SELECT l.*
FROM ip_log AS l
LEFT JOIN
(SELECT username
FROM player
WHERE status = 1 AND credit >= 1 AND username NOT LIKE '$user'
ORDER BY ls ASC, credit DESC
LIMIT 10) AS p
ON l.player = p.username
WHERE win = 1 and date = '$date'
AND p.username IS NULL
This shows the top 10 player data, except the ones with log messages in selection 2
SELECT p.*
FROM player AS p
LEFT JOIN ip_log AS l ON l.player = p.username AND l.win = 1 AND l.date = '$date'
WHERE p.status = 1 AND p.credit >= 1 AND p.username NOT LIKE '$user'
AND l.player IS NULL
ORDER BY p.ls ASC, p.credit DESC
LIMIT 10
In both cases, testing a column in the second table with IS NULL makes it return only the rows in the first table that don't have a match in the second table. See
Return row only if value doesn't exist
You can do it with LEFT JOIN
SELECT player.*,ip_log.* FROM `player` LEFT JOIN `ip_log` ON player.id!=ip_log.playerid GROUP BY player.id
Related
I want to create query that would show is the certain section is passed by certain account_id. It means all lessons of the section is checked = 1(true). I tried this solution:
SELECT count(*) as checked,(
SELECT count(*)
FROM lessons
WHERE section_id = 1
GROUP BY section_id
) as cnt, (checked = cnt) as passed
FROM lessons l
LEFT JOIN progress p ON l.id = p.lesson_id
WHERE l.section_id = 1 AND p.account_id = 3 AND checked = 1
GROUP BY l.section_id
But it returns error:
#1054 unknown 'cnt' column in field list.
What do I do wrong?
The unknown 'cnt' is generated from (checked=cnt) as passed. Try this
SELECT checked, cnt, (checked=cnt) as passed FROM (SELECT count(*) as checked,(
SELECT count(*)
FROM lessons
WHERE section_id = 1
GROUP BY section_id
) as cnt
FROM lessons l
LEFT JOIN progress p ON l.id = p.lesson_id
WHERE l.section_id = 1 AND p.account_id = 3 AND checked = 1
GROUP BY l.section_id) tblA
Note that you should move all conditions on the p.* columns to the ON clause. Otherwise you will convert the LEFT JOIN to an INNER JOIN and COUNT(*) will always be the same as in your subquery. However you don't even need that subquery - You can get the same value with COUNT(p.lesson_id) instead. It will ignore all rows with NULL.
SELECT
COUNT(*) as cnt,
COUNT(p.lesson_id) as checked,
COUNT(*) = COUNT(p.lesson_id) as passed
FROM lessons l
LEFT JOIN progress p
ON p.lesson_id = l.id
AND p.account_id = 3
AND p.checked = 1
WHERE l.section_id = 1
SELECT count(*) as checked, (SELECT count(*) FROM lessons
WHERE section_id = 1 GROUP BY section_id) as cnt,
((SELECT count(*) FROM lessons WHERE section_id = 1 GROUP BY section_id) = checked) pass
FROM lessons l LEFT JOIN progress p ON l.id = p.lesson_id
WHERE l.section_id = 1 AND p.account_id = 3 AND checked = 1 GROUP BY l.section_id
Thanks to #aynber. Though I'm not sure if this solution isn't too bulky.
My tables
$sql="SELECT *
FROM addresses
LEFT JOIN users ON address_id = user_id
LEFT JOIN notes ON note_id = user_id
ORDER BY id DESC
LIMIT 1";
This is my SQL query, my task is to show the last records from 3 tables, but the table is blank, I don't know why,thanks in advance people :)
I guess the problem is coming from the ORDER BY id DESC .
Indeed, you have no column so called id.
You should probably remove this clause, in order to make your code work.
If you want to take the last records anyway, you can put an ORDER BY address_id DESC which will do the job !
The code directly edited :
$sql="SELECT *
FROM addresses
LEFT JOIN users ON address_id = user_id
LEFT JOIN notes ON note_id = user_id
ORDER BY adress_id DESC
LIMIT 1";
This may work:
SELECT a.address_id, u.user_id, n.note_id
FROM addresses a
LEFT JOIN users_addresses ua ON ua.ua_address_id = a.address_id
LEFT JOIN users u ON u.user_id = ua.ua_user_id
LEFT JOIN notes n ON n.note_user_id = u.user_id
ORDER BY a.address_id DESC
LIMIT 1
Here is the query to get all data from all the tables, not sure what do you mean last records from 3 tables, I can see four tables there:
SELECT *
FROM `addresses`
LEFT JOIN `users_addresses` ON `users_addresses`.`ua_address_id` = `addresses`.`address_id`
LEFT JOIN `users` ON `users`.`user_id` = `users_addresses`.`ua_user_id`
LEFT JOIN `notes` ON `notes`.`note_user_id` = `users`.`user_id`;
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
I have a query that LEFT JOINS another table to group rows. I am trying to only select records from the first table "googleimage" where the user_id is a certain number. (user_id is a column in "googleimage" table.
SELECT g.*
FROM googleimage g
LEFT JOIN (SELECT image_id, COUNT(*) AS cnt
FROM googleimagefound WHERE status = 0
GROUP BY image_id) gf ON gf.image_id = g.id
ORDER BY COALESCE(cnt, 0) DESC");
I have tried adding a new ON statement beiside the
gf ON gf.image_id = g.id
I have also tried changing
SELECT g.*
FROM googleimage g
to
SELECT g.*
FROM googleimage WHERE user_id = 1 g
but none of them seem to work, any help will be appriciated
Try changing you query a bit like below
SELECT g.*
FROM googleimage g
LEFT JOIN (SELECT image_id, COUNT(*) AS cnt
FROM googleimagefound WHERE status = 0
GROUP BY image_id) gf ON gf.image_id = g.id
WHERE g.user_id = 1 <-- add this condition
ORDER BY COALESCE(gf.cnt, 0) DESC;
THIS IS THE OUTPUT OF THE QUERY:
SELECT * FROM
((SELECT
privatemsgs.id,
privatemsgs.useradn,
privatemsgs.useraid,
privatemsgs.title,
privatemsgs.created,
privatemsgs.timee,
privatemsgs.isread,
u.photo AS creatorphoto,
privatemsgs.relatedto
FROM privatemsgs
LEFT JOIN
users AS u ON(privatemsgs.useraid = u.id)
WHERE userbid='$myid'
AND relatedto=0 and bdel=1)
UNION
(SELECT
privatemsgs.id,
privatemsgs.useradn,
privatemsgs.useraid,
privatemsgs.title,
privatemsgs.created,
privatemsgs.timee,
privatemsgs.isread,
u.photo AS creatorphoto,
rel.relatedto
FROM privatemsgs AS rel
JOIN privatemsgs ON(rel.relatedto = privatemsgs.id)
LEFT JOIN
users AS u ON(rel.useraid = u.id)
WHERE rel.userbid='$myid'
)) privatemsgs
GROUP BY id
ORDER BY timee DESC
I got double id "2". first 1 with "isread = 0", second with "isread = 1".
When I added "group by id", I've got (line 2)
But i need the output to show that isread = 1 (like line 3)
How do i fix it?
add MAX(isread) near the *. GROUP BY works only on Aggregate functions