Oracle to MySQL Query Conversion - mysql

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;

Related

Subquery and Filter Eloquent Laravel using Yajra Datatables

I want to view bonus recapitulation from transaction and i try write code in phpmyadmin like
SELECT
tbl2.name, b.nama_bonus,
SUM(
CASE
WHEN b.nama_bonus REGEXP 'saldo' THEN tbl2.jumlah_transaksi * b.nominal_bonus
WHEN b.nama_bonus REGEXP 'bintang' AND tbl2.nama_kategori REGEXP 'transfer' THEN FLOOR(tbl2.total_nominal_transaksi / b.keterangan_bonus)
ELSE FLOOR(tbl2.total_nominal_transaksi / b.keterangan_bonus)
END
) AS bonus_member
FROM
(
SELECT tbl1.*, u.name, pc.nama_kategori, COUNT(tbl1.nominal_transaksi) AS jumlah_transaksi, SUM(tbl1.nominal_transaksi) AS total_nominal_transaksi FROM
(
SELECT no_invoice, product_category_id, nominal_transaksi, user_id, status_transaksi_id FROM transactions
WHERE status_transaksi_id = 1
) AS tbl1
JOIN users u ON u.id = tbl1.user_id
JOIN product_categories pc ON pc.id = tbl1.product_category_id
GROUP BY u.id, pc.id
) AS tbl2
JOIN bonus b ON b.product_category_id = tbl2.product_category_id
GROUP BY b.nama_bonus, tbl2.name
ORDER BY tbl2.name
And the result is result query image
how to implement mysql code with eloquent using yajra datatables and also filter the data?

use case statement in where clause conditional

Using the same query I am trying to list out notices which are not sent. I am closer to query but stuck in how to execute few conditions in where clause based upon certain condition.
I have tried the following query.
SELECT
vtn.*,
vn.v_notice_datetime
FROM
v_templates vt
JOIN v_template_notices vtn ON (vtn.v_template_id = vt.id)
JOIN violations v ON( v.v_template_id = vt.id )
LEFT JOIN vnotices vn ON(vn.vtemplate_notice_id = vtn.id)
WHERE
v.id = 1
AND vn.v_notice_datetime IS NULL
AND vtn.id > (
SELECT max(vn.vtemplate_notice_id)
FROM vnotices vn
WHERE vn.vnotice_datetime IS NOT NULL )
I want to cocatenate following sql code when vn.id IS NOT NULL
*AND vtn.id > ( SELECT max(vn.v_template_notice_id)
FROM v_notices vn WHERE vn.v_notice_datetime IS NOT NULL)*
Is CASE statement good option or any alternative? In research found that the CASE statement degrades the performance but I m not sure how to execute conditional statements in PostgreSQL / MySql?
Just a suggestion
You have left join table column involved in where this work as an inner join ..
you should move the condition for left joined table from where to ON condition
SELECT
vtn.*,
vn.v_notice_datetime
FROM v_templates vt
JOIN v_template_notices vtn ON (vtn.v_template_id = vt.id)
JOIN violations v ON( v.v_template_id = vt.id )
LEFT JOIN vnotices vn ON(vn.vtemplate_notice_id = vtn.id) AND vn.v_notice_datetime IS NULL
WHERE v.id = 1
AND vtn.id > (
SELECT max(vn.vtemplate_notice_id)
FROM vnotices vn
WHERE vn.vnotice_datetime IS NOT NULL )
;

mysql - sorting data from 2 tables by the value from the 3rd table

I would like to sort data from 2 different tables connected with UNION, sorting parameter has to come from from the 3rd table.(drivers > queno)
If I sort data from 1 table i use following code (works perfectly):
SELECT quotedb.*
FROM quotedb
LEFT JOIN drivers
ON quotedb.driver = drivers.id
ORDER BY IF(queno = ''
OR queno IS NULL, 1, 0)
So when I join 2 tables I tried with this with no succes...
(
SELECT DISTINCT driver
FROM quotedb
LEFT JOIN drivers
ON quotedb.driver=drivers.id)
UNION ALL
(
SELECT DISTINCT driver
FROM packaging
LEFT JOIN drivers
ON packaging.driver=drivers.id )
ORDER BY
order by IF(queno = ''
OR queno IS NULL,1,0)
What i need to do to make it work?. Thank you in advance.
You will need to fetch the queno column also from individual Select queries.
Try the following:
(
SELECT DISTINCT
qdb.driver AS driver,
d.queno AS queno
FROM quotedb AS qdb
LEFT JOIN drivers AS d ON qdb.driver = d.id
)
UNION ALL
(
SELECT DISTINCT
p.driver AS driver,
d.queno AS queno
FROM packaging AS p
LEFT JOIN drivers AS d ON p.driver = d.id
)
ORDER BY
(CASE WHEN queno = '' OR queno IS NULL THEN 1
ELSE 0
END)

Multiple Inner Join Concern

I'm trying to get data at monthly level.
SELECT
c.Calendar_Month_Name, COUNT(*)
FROM
db1 AS c
INNER JOIN
(SELECT DISTINCT
a.tel_num, b.postpaid_tel_num
FROM
db2 AS a
INNER JOIN db3 AS b ON a.tel_num = b.tel_num
WHERE
a.hs_manufacturer = 'Samsung'
AND b.postpaid_tel_num = 1) d ON c.Dim_Calendar_Dt = d.REPORT_DT
WHERE
c.Calendar_Year_Num = 2018
GROUP BY c.Calendar_Month_Name;
REPORT_DT is present in db2 but still I get an error that says REPORT_DT does not exist
If I change the position of paratheses as follows I get an error that says, something is expected between 'REPORT_DT' and the 'where' keyword.
SELECT
c.Calendar_Month_Name, COUNT(*)
FROM
(db1 AS c
INNER JOIN (SELECT DISTINCT
a.tel_num, b.postpaid_tel_num
FROM
db2 AS a
INNER JOIN db3 AS b ON a.tel_num = b.tel_num
WHERE
a.hs_manufacturer = 'Samsung'
AND b.postpaid_tel_num = 1) d ON c.Dim_Calendar_Dt = d.REPORT_DT
WHERE
c.Calendar_Year_Num = 2018)
GROUP BY c.Calendar_Month_Name;
In the first version, it looks like you need to add REPORT_DT to the select clause of your subquery d
FWIW, I think a formatted query should look something like this:
SELECT c.Calendar_Month_Name
, COUNT(*)
FROM db1 c
JOIN
( SELECT DISTINCT a.tel_num
, b.postpaid_tel_num
FROM db2 a
JOIN db3 b
ON a.tel_num = b.tel_num
WHERE a.hs_manufacturer = 'Samsung'
AND b.postpaid_tel_num=1
) d
ON c.Dim_Calendar_Dt = d.REPORT_DT
WHERE c.Calendar_Year_Num = 2018
GROUP
BY c.Calendar_Month_Name

Mysql query, select 2 databases with 4 tables + nested SELECT?

This is my current query:
$sel = "SELECT
db1t1.userid, db1t1.customer_id, db2t1.customers_id, db2t1.orders_id, db2t2.products_price
FROM
database1.table1 db1t1
LEFT JOIN database2.table1 db2t1 ON
db1t1.customer_id = db2t1.customers_id
LEFT JOIN database2.table2 db2t2 ON
db2t1.orders_id = db2t2.orders_id
WHERE db1t1.userid IN(
SELECT
l.userid, l.username, r.username, r.cus_id
FROM
database1.table3 l
LEFT JOIN database2.table4 r ON
l.username = r.username
WHERE r.cus_id = '1234'
)";
Error message:
Operand should contain 1 column(s)
The error occurred because that you returned a result with multiple columns to an IN clause.
Try this:
SELECT
`db1t1`.`userid`, `db1t1`.`customer_id`, `db2t1`.`customers_id`,
`db2t1`.`orders_id`, `db2t2`.`products_price`
FROM `database1`.`table1` AS `db1t1`
LEFT JOIN `database2`.`table1` AS `db2t1`
USING (`customers_id`)
LEFT JOIN `database2`.`table2` AS `db2t2`
USING (`orders_id`)
WHERE `db1t1`.`userid` IN (
SELECT `l`.`userid`
FROM `database1`.`table3` AS `l`
LEFT JOIN `database2`.`table4` AS `r`
USING (`username`)
WHERE `r`.`cus_id` = 1234
)
What are you trying to achieve ? Maybe we can find a better solution.
Also, I think that you should do an INNER JOIN instead of a LEFT JOIN in the subquery.