Is the syntax for join on stricter than using comma where? - mysql

The following query fails to be parsed:
select t.ename, t.received, d.loc from
(
select e.ename, eb.received , e.deptno
from emp e left outer join emp_bonus eb
on
e.empno=eb.empno
)
as t
join dept as d on d.deptno = t.deptno;
with the error:
Column 'deptno' in field list is ambiguous
But this query is parsed succesfully:
select t.ename, t.received, d.loc from
(
select e.ename, eb.received , e.deptno
from emp e left outer join emp_bonus eb
on
e.empno=eb.empno
)
as t, dept as d where d.deptno = t.deptno
I only changed the JOIN ON to t, dept where
Why does the first version fail?

the first query runs perfectly in mysql version 5.1
see the demo

Related

Oracle to MySQL Query Conversion

I was working on Oracle to MySQL query conversion when I encountered the following snippet that I'm completely unable to understand:
select *
from a, b
where a.liab_id = b.liability_no(+)
and NVL (a.cust_id, b.customer_no(+)) = b.customer_no(+);
Table a columns: cust_id, liab_id, details
Table b columns: customer_no, liability_no,range
I'd be really grateful if someone can explain the query or convert it to the respective MySQL query.
To convert the legacy Oracle comma join to the ANSI join syntax, you want:
SELECT *
FROM a
LEFT OUTER JOIN b
ON ( a.liab_id = b.liability_no
AND COALESCE( a.cust_id, b.customer_no ) = b.customer_no
)
or
SELECT *
FROM a
LEFT OUTER JOIN b
ON ( a.liab_id = b.liability_no
AND ( a.cust_id = b.customer_no OR a.cust_id IS NULL )
)
Oracle 18c db<>fiddle here
MySQL 8 db<>fiddle here
In both Oracle and MySQL, you should use explicit JOIN syntax. That would be:
select *
from a left join
b
on a.liab_id = b.liability_no and
a.cust_id = b.customer_no;

MYSQL - MAX() and GROUP BY() not results as expected

after running an sql
SELECT
m.stdClassID,
m.Percentage,
sc.ClassID,
sc.Form,
sc.FormName,
sc.Year,
sc.stdName
FROM stdremark m
INNER JOIN (
SELECT
sc.ClassID,
c.Form,
c.FormName,
sc.stdClassID,
c.Year,
CONCAT(s.StdFname,' ',s.StdLname) as stdName
FROM tblstdclass sc
INNER JOIN tblclass c
ON sc.ClassID=c.ClassID
INNER JOIN tblstudents s
ON sc.StdID = s.StdID
WHERE c.Year=2018
) sc ON m.stdClassID=sc.stdClassID
WHERE m.Term=3`
I come up with this result
I want to get the maximum percentage of each student grouped by the Form column
when I try to get Max() and group by()
from the sql:
SELECT
m.stdClassID,
MAX(m.Percentage),
sc.ClassID,
sc.Form,
sc.FormName,
sc.Year,
sc.stdName
FROM stdremark m
INNER JOIN (
SELECT
sc.ClassID,
c.Form,
c.FormName,
sc.stdClassID,
c.Year,
CONCAT(s.StdFname,' ',s.StdLname) as stdName
FROM tblstdclass sc
INNER JOIN tblclass c
ON sc.ClassID=c.ClassID
INNER JOIN tblstudents s
ON sc.StdID = s.StdID
WHERE c.Year=2018
) sc ON m.stdClassID=sc.stdClassID
WHERE m.Term=3
GROUP BY sc.Form`
the expected result should have been
17 71 28 upper Science 2018 Jerry Maguire
Could be an issue with MySQL allowing partial grouping. Try to extend your GROUP BY expression to group on all columns, except m.Percentage.
...
GROUP BY m.stdClassID,
sc.ClassID,
sc.Form,
sc.FormName,
sc.Year,
sc.stdName
Other DBMS would force you to do so anyway.

Conditional join to determine joining table

I have three tables emp, d1, d2. Tables d1 and d2 have almost same structure.
I need to join emp table with either d1 or d2 depending on the value of column deptno in emp table. My query which I have written is not working and giving syntax error:
Error Code: 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 'CASE
SELECT
e.`empno`,
e.`ename`,
e.`job`,
e.`mgr`,
e.`hiredate`,
e.`sal`,
e.`comm`,
e.`deptno`
FROM
`emp` e
JOIN
CASE
WHEN e.deptno <= 20
THEN
d1 ON e.deptno = d1.`deptno`
ELSE
d2 ON e.deptno = d2.`deptno`
END;
There is no such thing as a "conditional" join. You can do:
SELECT e.*,
COALESCE(d1.col1, d2.col1) as col1
FROM emp e LEFT JOIN
d1
ON e.deptno = d1.deptno AND e.deptno <= 20 LEFT JOIN
d2
ON e.deptno = d2.deptno AND e.deptno > 20;
Note that your query does not not select anything from the d1 or d2. In that sense, the JOIN is not needed at all. Note the logic in the SELECT for getting values from columns.
If you are using the joins for filtering, then add:
WHERE d2.deptno IS NOT NULL OR d1.deptno IS NOT NULL.
This is what a UNION SELECT is for:
SELECT e.`empno`, e.`deptno`
FROM `emp` e JOIN d1 ON e.deptno = d1.`deptno`
WHERE e.deptno <= 20
UNION
SELECT e.`empno`, e.`deptno`
FROM `emp` e JOIN d2 ON e.deptno = d2.`deptno`
WHERE e.deptno > 20
Just make sure that both selects pick same amount and type of columns.

Unknown field on INNER JOIN from multi databases

I have following sql statement:
INSERT INTO wk1_tbl (shohin_code, shohin_mei, variation_flag)
SELECT ha.HINCD, ha.HINNMA, if (g.goods_para_id IS NULL, 0, 1) AS variation
FROM ( SELECT KOSHINCD, count(HINCD) AS quatity
FROM sc.HINMTF
GROUP BY KOSHINCD ) AS group_set
INNER JOIN sc.HINMTA ha
ON ha.HINCD = group_set.KOSHINCD
INNER JOIN master_hankoya.goods g
ON ha.WEBHINID = g.goods_id 
WHERE ha.HINKB = '2' and ha.DATKB <> '9';
I using INNER JOIN on multi-database ,so that you can see sc and master_hankoya is difference databases
When I run it ,I get error :
Unknown column 'g.goods_id ' in 'on clause'
You can see g alias for table master_hankoya.goods,and goods_id is a column in this
I guess that I have problem with INNER JOIN
Please help me correct it
Update : I check again and take a silly problem ,have a special character in query make it failed to run
try this
INSERT INTO wk1_tbl (shohin_code, shohin_mei, variation_flag)
SELECT ha.HINCD, ha.HINNMA, if (g.goods_para_id IS NULL, 0, 1) AS variation
FROM ( SELECT KOSHINCD, count(HINCD) AS quatity
FROM sc.HINMTF
GROUP BY KOSHINCD ) AS group_set
INNER JOIN sc.HINMTA ha
ON ha.HINCD = group_set.KOSHINCD
INNER JOIN
(select * from master_hankoya.goods ) g
ON ha.WEBHINID = g.goods_id
WHERE ha.HINKB = '2' and ha.DATKB <> '9';
Don't use alias name for master_hankoya.goods like
INSERT INTO wk1_tbl (shohin_code, shohin_mei, variation_flag)
SELECT ha.HINCD, ha.HINNMA, if (master_hankoya.goods.goods_para_id IS NULL, 0, 1) AS variation
FROM ( SELECT KOSHINCD, count(HINCD) AS quatity
FROM sc.HINMTF
GROUP BY KOSHINCD ) AS group_set
INNER JOIN sc.HINMTA ha
ON ha.HINCD = group_set.KOSHINCD
INNER JOIN master_hankoya.goods
ON ha.WEBHINID = master_hankoya.goods.goods_id
WHERE ha.HINKB = '2' and ha.DATKB <> '9';
INNER JOIN sc.HINMTA ha
Change this line to:
INNER JOIN HINMTA AS ha
INNER JOIN master_hankoya.goods g
Change that line to
INNER JOIN goods AS g
The syntax for setting an alias for a table is:
table_name AS table_alias

subquery value outside the scope

SELECT IFNULL(oea.`name`,op.name) AS "Consultation"
FROM `a` ca
JOIN `b` oea ON ca.`consultation_id` = oea.id AND oea.status = 1
LEFT OUTER JOIN c oeal ON oea.`location_id` = oeal.id
WHERE oea.employee_profile_id IN (
SELECT profile_id
FROM d pp
WHERE pp.status='1'
UNION
SELECT op.id
FROM e op
WHERE op.status
) AND
ca.status = 1
I am getting this error
Unknown column 'op.name' in 'field list'
Is there any possibility to use op.name outside the scope?
JOIN the subquery in the WHERE clause instead of using the IN predicate. This way you can select the name from it.
But you didn't select the column name from in the subquery. You selected only the profile_id, you have to select it with the profile_id. Something like:
SELECT
IFNULL(oea.`name`, op.name) AS Consultation
FROM `a` ca
JOIN `b` oea ON ca.`consultation_id` = oea.id AND oea.status = 1
INNER JOIN
(
SELECT profile_id, name
FROM d pp
WHERE pp.status='1'
UNION
SELECT op.id, name
FROM e op
WHERE op.status
) AS op ON oea.employee_profile_id = op.profile_id
LEFT OUTER JOIN c oeal ON oea.`location_id` = oeal.id
WHERE ca.status = 1;
I assumed that the two tables have the name column, if one of them didn't have it, you have to use null instead.