About Mysql join case when error - mysql

select t.* FROM user_tq t join
CASE when t.blogid = 0 then user_dp ELSE user_blog END b
on t.uid = b.uid where ***;
I want to join different table according to blogid, when blogid is 0, join user_dp, else join user_blog.But it returns 1064 error.
How to solve this problem?

You can do this with left join and filter the right result by COALESCE
select t.*
FROM user_tq t
left join user_dp ud on t.blogid = 0 and t.uid = ud.uid
left join user_blog ub on t.blogid != 0 and t.uid = ub.uid
where
COALESCE(ud.uid, ub.uid) IS NOT NULL and
***;
For more info refer : MySQL query where JOIN depends on CASE
If you are trying to inner join to filter data on condition then;
select * from (
select t.*
FROM user_tq t
join user_dp ud on t.blogid = 0 and t.uid = ud.uid
union all
select t.*
FROM user_tq t
join user_blog ub on t.blogid != 0 and t.uid = ub.uid
) as x
where ****;

USE:
select * FROM users t
left join user_role r ON t.user_id = 0 AND r.user_id = t.user_id
left join product_category c ON t.user_id != 0 AND c.user_id = t.user_id
WHERE COALESCE(r.user_id, c.user_id) IS NOT NULL
WHERE ***;
Replace users, user_role and product_category with your tables.

The other answers posted here are the correct solutions.
I'll answer the "Why do I get 1064" for you.
The syntax you've written is invalid. You cannot "conditionally" join to a table like this.
What you can do is LEFT JOIN - which as opposed to [INNER] JOIN means "return NULL for all fields on this table if no record matches the join condition".
There's lots on the Internet about LEFT vs INNER joins, and MySQL's website documents the COALESCE function very well.
Have a play and a read, you'll figure it out why the other solutions work.
Upon reflection, I felt this could benefit from some additional explanation.
See this SQLFiddle: http://sqlfiddle.com/#!9/043b7/6

Related

conditional join between several tables of moodle's database

I need to create a join query between several tables based on the output of some previous table. I am trying to use case when statement as follows but its showing error! any kind of help is appreciated
SELECT completion.userid, completion. coursemoduleid, completion. timemodified,
module.course, user. idnumber as student_id, m.name as module_name, activity.name as activity_name
FROM `mdl_course_modules_completion` as completion
join mdl_course_modules as module
on completion. coursemoduleid = module.id
join mdl_user as user on user.id = completion.userid
join mdl_modules as m on completion. coursemoduleid = m.id
join
CASE WHEN module_name = 'assign'THEN 'mdl_assign'
WHEN module_name = 'assignment' THEN 'mdl_assignment'
ELSE "quiz"
END AS activity
on activity.id = m.id LIMIT 0, 30
There is no such thing as "conditional join". Instead you can use two LEFT JOINs and COALESCE():
SELECT completion.userid,
...
COALESCE(activity1.name, activity2.name) as activity_name -- SELECT first non NULL value
FROM `mdl_course_modules_completion` as completion
...
LEFT JOIN mdl_assign activity1
ON activity1.id = m.id -- JOIN condition
AND module_name = 'assign' -- CASE condition
LEFT JOIN mdl_assignment activity2
ON activity2.id = m.id -- JOIN condition
AND module_name = 'assignment' -- CASE condition
Hope this will help you -
SELECT completion.userid, completion. coursemoduleid, completion. timemodified,
module.course, user. idnumber as student_id, m.name as module_name,(CASE WHEN (a.name != '') THEN a.name ELSE (CASE WHEN (ass.name != '') THEN ass.name ELSE q.name END) END) as activity_name
FROM `mdl_course_modules_completion` as completion
join mdl_course_modules as module
on completion. coursemoduleid = module.id
join mdl_user as user on user.id = completion.userid
join mdl_modules as m on completion. coursemoduleid = m.id
left join mdl_assign as a on a.id = m.id
left join mdl_assignment as ass on ass.id = m.id
left join mdl_quiz as q on q.id = m.id
where m.name in ('assign','assignment','quiz')
LIMIT 0, 30

How can I check whether the column data is present in other table in mysql?

I have 3 tables say Jobs, results, ordered, I have joined 'jobs' and 'results' table (using jobID ) and I need to check the whether the result ID is present in orders tables or not, if present it should print Yes or else no
set #sno:=0; SELECT #sno:=#sno+1 Id, j.job_id,gr.name as Group_name, u.name User_name, p.name Project_name, j.version,j.type,vendor,tech, functionality as Algo,words,bits,freq, j.status,r.macroId, CASE WHEN o.macroId IS NULL THEN 'No' ELSE 'Yes' END Ordered, j.cmd_line,j.submit_date FROM job j JOIN cut_results_vw r ON j.job_id = r.jobId LEFT OUTER JOIN project p ON j.project_id = p.project_id LEFT OUTER JOIN user u ON j.user_id = u.user_id LEFT OUTER JOIN groups gr ON j.group_id = gr.group_id LEFT JOIN ordered_cuts o ON r.macroId = o.macroId
select j.*,
case when o.resultid is not null
then 'yes'
else 'no'
end as present
from jobs j
inner join results r on r.jobid = j.jobid
left outer join orders o on o.resultid = r.resultid
It's hard to tell without seeing your actual table schemas, but you can try it this way
SELECT j.*, r.*,
CASE WHEN o.resultid IS NULL THEN 'No' ELSE 'Yes' END resultid_is_present
FROM jobs j JOIN results r
ON j.jobid = r.jobid LEFT JOIN ordered o
ON r.resultid = o.resultid
To better understand JOINs read
A Visual Explanation of SQL Joins

How do I use an IF statement in an MySQL join query?

I have a SQL query that left joins a table in different ways depending on a condition.
SELECT m.id, u.first_name AS otherUser
FROM matches AS m
IF (u.id=m.user2ID)
LEFT JOIN users AS u ON u.id = m.user1ID
ELSE
LEFT JOIN users AS u ON u.id = m.user2ID
ENDIF
WHERE m.user1ID=2 OR m.user2ID=2
matches is a table with integer columns user1ID and user2ID. users is a table containing users of my web application. users has a VARCHAR field called first_name.
The intention of this query is to get the names of the users matched with the current user.
However, MySQL returns this error:
#1064 - 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 'IF (u.id=m.user2ID) LEFT JOIN users
AS u ON u.id = m.user1ID ELSE LEFT JOIN user' at line 3
Why?
Specify the condition as part of the ON clause:
SELECT m.id, u.first_name AS otherUser
FROM matches AS m
LEFT JOIN users AS u ON (u.id=m.user2ID and u.id = m.user1ID) or (u.id<>m.user2ID and u.id = m.user2ID)
WHERE m.user1ID=2 OR m.user2ID=2
Another way to do the same thing:
SELECT m.id, u.first_name AS otherUser
FROM matches AS m
LEFT JOIN users AS u ON IF(u.id=m.user2ID,u.id = m.user1ID,u.id = m.user2ID)
WHERE m.user1ID=2 OR m.user2ID=2
Use this query:
SELECT m.id, u.first_name AS otherUser FROM matches AS m LEFT
JOIN users AS u ON u.id = m.user1ID AND u.id=m.user2ID LEFT JOIN users
AS u1 ON u1.id = m.user2ID WHERE m.user1ID=2 OR m.user2ID=2
Updated query:
SELECT m.id, u.first_name AS otherUser
FROM matches AS m
LEFT JOIN users AS u ON u.id = (CASE WHEN u.id=m.user2ID
THEN m.user1ID
ELSE m.user2ID
END)
WHERE m.user1ID=2 OR m.user2ID=2
Check this Source.
Also check this MYSQL Inner Join if statement . It might be helpful for you.
You can also have two LEFT JOIN on the same table like this...
LEFT JOIN users AS u ON u.id = m.user1ID
LEFT JOIN users AS u2 ON u2.id = m.user2ID
This is an alternative to using IF statements.
You can not use the IF THEN ELSE END IF-stuff in a SELECT in this way. However, you can use it in stored procedures and functions.
I would JOIN u.id with both m.user1ID and m.user2ID and use DISTINCT to avoid duplicates.
There is a IF() which you can use in SELECTs, but you can not do flow control with IF().
Thanks,
It worked for me. Tried something else like below :
**
Create table TEMP1 (ID INT,T_MONTH INT,T_YEAR INT)
INSERT INTO TEMP1 VALUES(1,1,2001)
INSERT INTO TEMP1 VALUES(2,2,2001)
INSERT INTO TEMP1 VALUES(3,3,2001)
**
CREATE TABLE TEMP2 (T_MONTH INT,T_YEAR INT,FREQUENCY CHAR(1),VAL FLOAT)
INSERT INTO TEMP2 VALUES(1,2001,'M',1.1)
INSERT INTO TEMP2 VALUES(3,2001,'M',1.2)
INSERT INTO TEMP2 VALUES(3,2001,'Q',1.3)
INSERT INTO TEMP2 VALUES(12,2001,'A',1.4)
SELECT * FROM TEMP1 L JOIN TEMP2 H
ON L.T_YEAR = H.T_YEAR
OR (L.T_MONTH = (CASE WHEN H.FREQUENCY='M'
THEN H.T_MONTH
END)
OR dbo.GetQuarterFromMonth(L.T_MONTH) = (CASE WHEN H.FREQUENCY = 'Q'
THEN dbo.GetQuarterFromMonth(H.T_MONTH)
END))
WHERE H.FREQUENCY = 'Q'
Here GetQuarterFromMonth is a user defined funtion which returns Quarter for a particular month.
The objective of above query is to inflate the value of Quarter for all the months in table 1. If frequency is annual then in that case the value should be inflated for all the months 1-12 of table 1 which is achieved through first join condition. In case frequency is Monthly then each month from table1 should be mapped to table2. The only unique case is handling quarter frequency.

MySQL: IS NULL in joined tables

I'm having some difficulty with my JOIN and IS NULL..
Basically what I want to do is find all members who are not apart of certain group category ID's that I specify.
SELECT m.* FROM elvanto_members AS m
LEFT JOIN elvanto_groups AS g ON g.deleted = 0
LEFT JOIN elvanto_groups_categories AS gc ON gc.group_id = g.id AND (gc.category_id = '1' OR gc.category_id = '2')
WHERE gr.id IS NULL
Some members aren't apart of any group categories at all which is why I've made it a LEFT JOIN.
Am I making sense? Do you have any idea how to fix this?
Try this:
SELECT m.* FROM elvanto_members AS m
WHERE
not exists
(
SELECT 1 FROM
elvanto_groups AS g
INNER JOIN elvanto_groups_categories AS gc ON
gc.group_id = g.id
WHERE
gc.category_id IN ('1','2') AND
g.id = m.group_id AND
g.deleted = 0
)
SELECT m.*
FROM elvanto_members AS m
LEFT JOIN elvanto_groups AS g ON g.id = m.group_id AND g.deleted = 0
LEFT JOIN elvanto_groups_categories AS gc ON gc.group_id = g.id
AND gc.category_id IN ('1','2')
WHERE gc.group_id IS NULL
GROUP BY m.*
I filled in on spec what was missing in the question.
Is category_id really a string type? I would expect it to be numeric. Then this expression should be:
AND gc.category_id IN (1,2)

MySQL Not unique table/alias

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
)