I have a query like this
left outer join ( select tm.item_id as item_id,function_role =(CASE
mf.function_name
when mf.function_name is not null
then mf.function_name
else 'admin'
end)
from team_members tm
join mem_function mf on mf.function_id=tm.function_id
) bnu on bnu.item_id = p.pro_id
When there's NO value in the function_name column of mem_function table,I want to set that value as 'admin'.
when i tried this it's throwing "From keyword not found where expected"
anyway to resolve this?
Is this what you want?
left outer join
(select tm.item_id as item_id,
coalesce(function_name, 'admin') as function_role
from team_members tm join
mem_function mf
on mf.function_id = tm.function_id
) bnu
on bnu.item_id = p.pro_id
Although you can do this using case, coalesce() is really the better solution.
I think your problem involves the function_role =. That assigns a variable, not a column name.
EDIT:
Your problem seems to be in the outer query. So you want:
select . . ., coalesce(function_name, 'admin') as function_role
from . . .
left outer join
(select tm.item_id as item_id, function_name
from team_members tm join
mem_function mf
on mf.function_id = tm.function_id
) bnu
on bnu.item_id = p.pro_id
You probably don't need the subqueries, but that is another matter.
Related
select `tbl_users`.`username`, `tbl_users`.`users_id`, `tbl_users`.`profile_picture`,
(select count(users_id) from tbl_movies_comments where users_id = `tbl_users`.`users_id`) as UsersCommentsCount,
(select count(users_id) from tbl_movies_reviews where users_id = `tbl_users`.`users_id`) as UserReviewsCount
left join `tbl_movies_comments` on `tbl_users`.`users_id` = `tbl_movies_comments`.`users_id`
left join `tbl_movies_reviews` on `tbl_users`.`users_id` = `tbl_movies_reviews`.`users_id`
group by `tbl_users`.`username`, `tbl_users`.`users_id`, `tbl_users`.`profile_picture`, `tbl_movies_comments`.`users_id`, `tbl_movies_reviews`.`users_id`
Your statement is really bad formatted. This is one reason why its hard to debug code...
....
(
SELECT
Count(users_id)
FROM
tbl_movies_reviews
WHERE
users_id = tbl_users.users_id
) AS userreviewscount
FROM yourtablename <<<--- Missing
left JOIN tbl_movies_comments
ON tbl_users.users_id = tbl_movies_comments.users_id
....
Use tools like HeidiSQL or an online Syntax formatter/checker to avoid such situations
There is no FROM clause in your query.
SELECT ...
FROM `tbl_users`
LEFT JOIN ...
how to increase the performance of this mysql query
SELECT '' AS sharedid,
hubber_posts.userID AS postowner,
hubber_posts.*,
'' AS sharedby,
hubber_posts.userID AS userID,
hubber_posts.posted_date AS DATE,
'' AS sharebyusr,
'' AS sharebyusrimg,
Concat_ws(' ', firstname, lastname) AS fullname,
username AS postedBy,
hubber_user.image,
hubber_user.gender AS gender,
(SELECT accounttype
FROM hubber_user_security us
WHERE hubber_user.ID = us.userID
AND hubber_posts.userID = us.userID) AS accounttype,
'' AS sharebyusrtype
FROM hubber_posts
INNER JOIN hubber_user
ON hubber_posts.userID = hubber_user.ID
WHERE hubber_posts.status = 1
Your example code has a correlated subquery. MySQL performs poorly with those, as of late 2016.
Try converting it to a JOINed table.
SELECT all that stuff,
us.accounttype
FROM hubber_posts
JOIN hubber_user ON hubber_posts.userID = hubber_user.ID
LEFT JOIN hubber_user_security us ON hubber_user.ID = us.userID
WHERE hubber_posts.status = 1
I used LEFT JOIN. Without the LEFT, any rows without a matching entry in that table will be suppressed from the result set.
You query is essentially this:
SELECT . . .
(SELECT accounttype
FROM hubber_user_security us
WHERE u.ID = us.userID AND
p.userID = us.userID
) AS accounttype,
. . .
FROM hubber_posts p INNER JOIN
hubber_user u
ON p.userID = u.ID
WHERE p.status = 1 ;
For this query, the optimal indexes are:
hubber_posts(status, userId)
hubber_user(Id)
hubber_user_security(userId)
I would note that the subquery has an extra correlation condition that is not necessary -- the user ids are already equal. And, you run the risk of getting an error if there are multiple account types.
You may intend:
(SELECT GROUP_CONCAT(accounttype)
FROM hubber_user_security us
WHERE u.ID = us.userID
) as accounttypes,
My suggestion is to support a join where hubber_posts is the base table and the 2 other tables are joined using nested loops.
No need to index hubber_posts for the join.
hubber_user.ID should be a PK.
hubber_user_security.userID should be indexed (and defined as a FK references hubber_user.ID).
As for the WHERE clause - only if you have relatively few rows where hubber_posts.status = 1 then you should add an index on hubber_posts.status
P.s.
since the join contain the condition -
ON hubber_posts.userID = hubber_user.ID
There is no need to compare both hubber_posts.userID and hubber_user.ID to us.userID
I'm trying to left join the second table useri_ban based on the users' ids, with the extra condition: useri_ban.start_ban = max_start.
In order for me to calculate max_start, I have to run the following subquery:
(SELECT MAX(ub.start_ban) AS max_start, user_id FROM useri_ban ub WHERE ub.user_id = useri.id)
Furthermore, in order to add max_start to every row, I need to inner join this subquery's result into the main result. However, it seems that once I apply that join, the subquery is no longer able to access useri.id.
What am I doing wrong?
SELECT
useri.id as id,
useri.email as email,
useri_ban.warning_type_id as warning_type_id,
useri_ban.type as type,
useri.created_at AS created_at
FROM `useri`
inner join
(SELECT MAX(ub.start_ban) AS max_start, user_id FROM useri_ban ub WHERE ub.user_id = useri.id) `temp`
on `useri`.`id` = `temp`.`user_id`
left join `useri_ban` on `useri_ban`.`user_id` = `useri`.`id` and `useri_ban`.`start_ban` = `max_start`
Does this solve your problem? You need GROUP BY in the inner query instead of another join.
SELECT useri.id, useri.email, maxQuery.maxStartBan
FROM useri
INNER JOIN
(
SELECT useri_ban.user_id ubid, MAX(useri_ban.startban) maxStartBan
FROM useri_ban
GROUP BY useri_ban.user_id
) AS maxQuery
ON maxQuery.ubid = useri.id;
I want to use subquery inside of IFNULL statement
SELECT t.col1
, IFNULL(t.col2, (SELECT an.col_11
FROM another_table an
WHERE an.col1 = t.col5)) as alias_name
, t.col3
FROM table t;
In IFNULL statement second expression should be subquery.
Please give me proper syntax
My actual query is
SELECT u.username, up.gender, d.name, desg.name,
IFNULL(up.creative_lead_id,
(SELECT au.username FROM auth_user au
WHERE au.id=up.creative_lead_id)) as creative_lead, up.image
FROM user_profile up, department d, designation, auth_user
WHERE up.department_id=d.id
AND up.designation_id = desg.id up.auth_uesr_id = u.id;
This query is giving syntax error because of IFNULL statement.
You can rewrite your query with join,Correlated query will execute for each row in your table and it might affect the performance
SELECT
t.col1,
IFNULL(t.col2, an.col_11) AS alias_name,
t.col3
FROM
`table` t
LEFT JOIN another_table an
ON an.col1 = t.col5
Don't use a subquery for this situation, try a query like that instead (use of jointure):
SELECT t.col1
,IFNULL(t.col2, an.col_11) AS alias_name
,t.col3
FROM your_table t
LEFT JOIN another_table an ON an.col1 = t.col5
In your full query, your using twice up.creative_lead_id for your IFNULL clause (once as first parameter and then in the subquery). That make no sense because if the first param is NULL, your subquery will return no result!
In order to show you the principe that will solve your problem, i just replaced the first param by a fictive one that i called up.creative_lead. This fictive column is the name of the creative lead stored in your table user_profile and if this value is null, i'm looking to the username of the user corresponding to creative_lead_id.
Here is the full query that'll solve your problem with the correction mentioned above:
SELECT u.username
,up.gender
,d.name
,desg.name
,IFNULL(up.creative_lead, cl.username) AS creative_lead
,up.image
FROM user_profile up
INNER JOIN department d ON d.id = up.department_id
INNER JOIN designation desg ON desg.id = up.designation_id
INNER JOIN auth_user u ON u.id = up.auth_user_id
INNER JOIN auth_user cl ON cl.id = up.creative_lead_id
Notice that i changed the syntax of your query, it's highly recommended to avoid the use of old syntax for jointures (use explicit JOIN clause instead).
Hope this will help you.
I have a litte problem with a mysql query.
I use 5 tables:
user_has_data (uid, dataid); users (uid, uname); user_in_group(uid, groupid, data); groups(groupid, data, packageid); packages(packageid, name)
all ids are PK. I want to build a sql query that finds a user, which belongs to a specified dataid, by its uname and checks if the user is in a group (relation in table user_in_group) belonging to a specified package (a group is assigned to one package). if so data from users, package and group should be fetched, otherwise only the user data should be fetched. Therefore I use left joins, so I can also get the users with no group:
SELECT `uac`.`uid`, `u`.`uid`, `uig`.`groupid`, `ag`.`packageid`
FROM `user_has_data` AS `uac`
INNER JOIN `users` AS `u` ON u.uid = uac.uid
LEFT JOIN `user_in_group` AS `uig` ON uig.uid = uac.uid
LEFT JOIN `groups` AS `ag` ON (ag.groupid = uig.groupid) AND (ag.packageid = 2)
WHERE (uac.dataid = '3') AND (u.uname LIKE 'test%')
GROUP BY `u`.`uid`
Unfortunately I get wrong results: I get groups that have a different packageid than stated in the join, if the user has another group assigned to him with a different packageid.
probably this is because the first left join has no restrictions to packageid and the second is a left join and so it has no restrictions on the result (packageid is NULL for all results, but should have values). If I change the second left join to a ordinary join, the group problem would be fixed but the query cant find users without group any more.
Any ideas how to fix this or even possible?
thanks in advance!
Are you saying that you are actually seeing the value ag.packageid = 2 in your query results?
If not, I think you might try something like:
SELECT `uac`.`uid`, `u`.`uid`, `g`.`groupid`, `g`.`packageid`
FROM `user_has_data` AS `uac`
INNER JOIN `users` AS `u` ON u.uid = uac.uid
LEFT JOIN (`user_in_group` AS `uig`
INNER JOIN `groups` AS `ag` ON (ag.groupid = uig.groupid) AND (ag.packageid = 2) )
AS `g` ON uac.uid = g.uid
WHERE (uac.dataid = '3') AND (u.uname LIKE 'test%')
GROUP BY `u`.`uid`
Because you are limiting your search to a specific group packageid of '2', why not just make both of your LEFT JOIN INNER JOINS and then throw in ag.packageid = 2 in your WHERE clause?
SELECT `uac`.`uid`, `u`.`uid`, `uig`.`groupid`, `ag`.`packageid`
FROM `user_has_data` AS `uac`
INNER JOIN `users` AS `u` ON u.uid = uac.uid
LEFT OUTER JOIN `user_in_group` AS `uig` ON uig.uid = uac.uid
LEFT OUTER JOIN `groups` AS `ag` ON ag.groupid = uig.groupid
WHERE (uac.dataid = '3') AND (u.uname LIKE 'test%')
AND (ag.packageid = 2 OR uig.uid IS NULL)
GROUP BY `u`.`uid`
I know LEFT JOIN and LEFT OUTER JOIN mean the same thing, but I like to be explicit. With the condition in your join, I bet you were getting groups with different packages, but weren't getting the packages?