I looked at the answers of others having the same problem, but I can't figure out how to fix the "Not unique table/alias".
SELECT m.*, u.*
FROM ".TABLE_PREFIX."users_medals u
LEFT JOIN ".TABLE_PREFIX."medals m ON u.medal_id = m.medal_id
WHERE u.user_id IN (".$post['uid'].")
AND m.medal_level = (
SELECT MAX(".TABLE_PREFIX."medals.medal_level) FROM ".TABLE_PREFIX."medals
LEFT JOIN ".TABLE_PREFIX."medals ON ".TABLE_PREFIX."users_medals.medal_id = ".TABLE_PREFIX."medals.medal_id
WHERE ".TABLE_PREFIX."users_medals.user_id = u.user_id
AND ".TABLE_PREFIX."medals.medal_type = m.medal_type
)
TABLE_PREFIX is what my script uses to define the database table prefix.
In your sub-query
LEFT JOIN ".TABLE_PREFIX."medals
I think that should be
LEFT JOIN ".TABLE_PREFIX."users_medals
In the subquery you have two medals tables without aliases. I think the FROM ".TABLE_PREFIX."medals should be FROM ".TABLE_PREFIX."users_medals:
SELECT m.*, u.*
FROM ".TABLE_PREFIX."users_medals u
LEFT JOIN ".TABLE_PREFIX."medals m ON u.medal_id = m.medal_id
WHERE u.user_id IN (".$post['uid'].")
AND m.medal_level = (
SELECT MAX(".TABLE_PREFIX."medals.medal_level) FROM ".TABLE_PREFIX."users_medals
LEFT JOIN ".TABLE_PREFIX."medals ON ".TABLE_PREFIX."users_medals.medal_id = ".TABLE_PREFIX."medals.medal_id
WHERE ".TABLE_PREFIX."users_medals.user_id = u.user_id
AND ".TABLE_PREFIX."medals.medal_type = m.medal_type
)
Related
I want join this tables in only query mysql, I'm trying but it doesn't work.
I want get by idtravel as this pseudocode:
select *
from travel t
left join user
left join vehicule
where idtravel = ?
select *
from
(select *
from vehicle v
left join user u on v.user_idv= u.id
select *
from travel t
left join user u on t.user_idt= u.id) as res
select *
from travel t
left join `user` u on u.id = t.user_idt
left join vehicle v on u.id = v.user_idv
where t.idtravel = ?
SELECT user.*, vehicle.name as vehicale_name, travel.* FROM user
left join `vehicle` on vehicle.user_id = user.id
left join `travel` on travel.user_id = user.id
where travel.idtravel = ?
SELECT * FROM user u
LEFT JOIN travel t ON u.id = t.user_idt
LEFT JOIN vehicle v ON u.id = v.user_idv
WHERE t.idtravel = ?;
i get an error got when i put this is my phpmyadmin sql,
error code #1052.
SELECT *
FROM users u
LEFT
JOIN user_tokens t
ON u.userid = u.id
LEFT
JOIN jt_campings_users cu
ON cu.userid = u.id
LEFT
JOIN campings c
ON c.user_id = u.id
WHERE id = 9271
You will have to give query hint to optimizer to where id is coming from because that might be possibility id is available in one or more tables :
WHERE u.id = 9271
So, the best practise to avoid such error is to use alias :
SELECT <column list> -- Do not use `*`, always qualify column list
FROM `users` u LEFT JOIN -- i removed LEFT JOIN user_tokens t as no mapping available
`jt_campings_users` jt
ON jt.userid = u.id LEFT JOIN
`campings` c
ON c.user_id = users.id
WHERE u.id = 9271;
I have the following query:
SELECT u.id, u.name, u.date_registered, p.time_created
FROM users u JOIN
prospect_notes p
ON u.id=p.subject_id
WHERE u.allocated_instructors = 668
AND p.time_created = (SELECT MAX(p2.time_created) FROM prospect_notes p2 WHERE p2.subject_id = p.subject_id)
ORDER BY p.time_created;
My problem is that when there are no rows in the prospect_notes table which match the following:
AND p.time_created = (SELECT MAX(p2.time_created) FROM prospect_notes p2 WHERE p2.subject_id = p.subject_id)
I get no result.
Instead, I want all the rows in the users table to return (presumably p.time_created would be NULL in such cases).
You need to be careful because of the JOIN clause. Presumably, if there are no matches for the correlated subquery, there are no matches in the JOIN either.
So, use LEFT JOIN and move the logic to the FROM clause:
SELECT u.id, u.name, u.date_registered, p.time_created
FROM users u LEFT JOIN
prospect_notes p
ON u.id = p.subject_id LEFT JOIN
(SELECT p2.subject_id, MAX(p2.time_created) as max_time_created
FROM prospect_notes p2
GROUP BY p2.subject_id
) p2
ON p2.subject_id = p.subject_id AND p2.time_created = p.time_created
WHERE u.allocated_instructors = 668
ORDER BY p.time_created;
That said, if you only want time_created from prospect_notes, then use a simpler query:
SELECT u.id, u.name, u.date_registered, MAX(p.time_created)
FROM users u LEFT JOIN
prospect_notes p
ON u.id = p.subject_id
WHERE u.allocated_instructors = 668
GROUP BY u.id -- okay, assuming id is unique or a primary key
ORDER BY MAX(p.time_created);
You need LEFT JOIN this clause permit you to have NULL values in the right table.
Try :
SELECT u.id, u.name, u.date_registered, p.time_created
FROM users u
LEFT JOIN prospect_notes p
ON u.id=p.subject_id
WHERE u.allocated_instructors = 668
AND p.time_created = (SELECT MAX(p2.time_created) FROM prospect_notes p2 WHERE p2.subject_id = p.subject_id)
ORDER BY p.time_created;
I have a query with one LEFT JOIN that works fine. When I add a second LEFT JOIN to a table with multiple records per field in the first table, however, I am getting the product of the results in the two tables ie books x publishers returned. How can I prevent this from happening?
SELECT a.*,b.*,p.*, group_concat(b.id as `bids`)
FROM authors `a`
LEFT JOIN books `b`
ON b.authorid = a.id
LEFT JOIN publishers `p`
on p.authorid = a.id
GROUP by a.id
EDIT:
Figured it out. The way to do this is to use subqueries as in this answer:
SELECT u.id
, u.account_balance
, g.grocery_visits
, f.fishmarket_visits
FROM users u
LEFT JOIN (
SELECT user_id, count(*) AS grocery_visits
FROM grocery
GROUP BY user_id
) g ON g.user_id = u.id
LEFT JOIN (
SELECT user_id, count(*) AS fishmarket_visits
FROM fishmarket
GROUP BY user_id
) f ON f.user_id = u.id
ORDER BY u.id;
If you do multiple LEFT Joins, your query will return a cartesian product of the results. To avoid this and get only one copy of fields you desire, do a subquery for each table you wish to join as below. Hope this helps someone in the future.
SELECT u.id
, u.account_balance
, g.grocery_visits
, f.fishmarket_visits
FROM users u
LEFT JOIN (
SELECT user_id, count(*) AS grocery_visits
FROM grocery
GROUP BY user_id
) g ON g.user_id = u.id
LEFT JOIN (
SELECT user_id, count(*) AS fishmarket_visits
FROM fishmarket
GROUP BY user_id
) f ON f.user_id = u.id
ORDER BY u.id;
i'm trying to build a chat application, in which i have these four tables
chat --id,group_id,body,time_posted[timestamp]
chat_groups --establish id,name for a group
users_groups --link users to a group, also define if user stared this group FIELDS::user_id,group_id,stared[bool]
wall_visit --user_id,group_id,last_visit[timestamp]
the idea is every users join a group, and they post to it in chat.
chat_groups table is just for defining the room, while users_groups is for setting access of members to this group.
wall_visit table is a table that store specific user last time accessed specific group (since its many to many u know..)
now what im trying to establish is to get in one query,
the chat_groups the user in relation with
the count of messages posted to this group since user last login (from settings)
the count of members in this group
the group name
:)
i have been trying to hours now :( best i could come up with
SELECT w.last_visit,access.stared,cg.user_id,u.fullname as username,cg.name as group_name ,cgu.count_members,c.count_msgs,c.time_posted
FROM `chat_groups`cg
inner join chat_groups_users access on (access.group_id = cg.id and access.user_id = ?)
left outer join users u on u.id = cg.user_id
left join wall_visit w on w.group_id = cg.id
left join (select count(*) as count_members,group_id from group_users group by group_id) cgu on cgu.group_id = cg.id
left join (SELECT count(wv.id) as count_msgs,c.group_id,c.time_posted FROM chats c
left outer join `wall_visit` wv on (wv.group_id is not null and c.group_id = wv.group_id and c.time_posted > wv.last_visit)
group by c.group_id) c on c.group_id = cg.id
where cg.user_id = 1
this query is working ..ehh, my main problem is with the count of the messages in the group since last_visit.
what is the best methode to get message_count to work :( ??
can this query be optimized more?
Thanks SO community :)
My 2nd attempt
SELECT w.last_visit,access.stared,cg.user_id,u.fullname as username,cg.with_id,uu.fullname as with_name,cg.name as group_name ,cgu.count_members,c.count_msgs,c.time_posted
FROM `chat_groups`cg
inner join chat_groups_users access on (access.group_id = cg.id and access.user_id = 1)
left outer join users u on u.id = cg.user_id
left join wall_visit w on w.chat_id = cg.id
left outer join users uu on uu.id = cg.with_id
left join (select count(*) as count_members,group_id from chat_groups_users group by group_id) cgu on cgu.group_id = cg.id
left join (
SELECT group_id,count(c.id) as count_msgs,time_posted FROM `chats` c inner join wall_Visit wv on wv.chat_id = c.group_id where c.id > wv.last_visit group by c.group_id
) c on c.group_id = cg.id
where cg.user_id = 1
this should fix you count message problem
SELECT
`cg`.`user_id`, `cg`.`with_id`, `cg`.`name` AS `group_name`,
`access`.`stared`,
`u`.`fullname` AS `username`,
`w`.`last_visit`,
`uu`.`fullname` AS `with_name`,
`cgu`.`count_members`,
`c`.`count_msgs`, `c`.`time_posted`
FROM `chat_groups` AS `cg`
INNER JOIN `chat_groups_users` AS `access`
ON (`access`.`group_id` = `cg`.`id` AND `access`.`user_id` = `cg`.`user_id`)
LEFT OUTER JOIN `users` AS `u`
ON (`u`.`id` = `cg`.`user_id`)
LEFT JOIN `wall_visit` AS `w`
ON (`w`.`chat_id` = `cg`.`id`)
LEFT OUTER JOIN `users` AS `uu`
ON (`uu`.`id` = `cg`.`with_id`)
LEFT JOIN (
SELECT COUNT(*) AS `count_members`, `group_id`
FROM `chat_groups_users`
GROUP BY
`group_id`
) AS `cgu`
ON (`cgu`.`group_id` = `cg`.`id`)
LEFT JOIN (
SELECT count(`c`.`id`) AS `count_msgs`, `c`.`time_posted`
FROM `chats` AS `c`
INNER JOIN `wall_visit` AS `wv`
ON (`wv`.`chat_id` = `c`.`group_id`)
WHERE
`c`.`time_posted` > `wv`.`last_visit`
GROUP BY
`c`.`group_id`
) AS `c`
ON (`c`.`group_id` = `cg`.`id`)
WHERE `cg`.`user_id` = 1
otherwise u have to setup a fiddle