Re-arrange a MySQL nested query - mysql

How can i redo the following query to use only JOINs instead of the nested query?
SELECT SUM(allqty) AS allqty
,COUNT(*) AS orders
FROM (SELECT SUM(S.Qty) AS allqty
FROM data_intra.yw1_ordersheet S
INNER JOIN data_intra.productdata P ON P.productid=S.productid
WHERE P.eCode LIKE (SELECT eCode
FROM data_intra.productdata
WHERE productid=1001)
GROUP BY S.OrderPO) as A;

Here are 2 guesses. Both use IN() instead of LIKE()
This will produce one row for each S.OrderPO
SELECT
SUM(S.Qty) AS allqty
, S.OrderPO
FROM data_intra.yw1_ordersheet S
INNER JOIN data_intra.productdata P
ON P.productid = S.productid
WHERE P.eCode IN (
SELECT
eCode
FROM data_intra.productdata
WHERE productid = 1001
)
GROUP BY
S.OrderPO
;
This will produce one row, counting the distinct number of S.OrderPO
SELECT
SUM(S.Qty) AS allqty
, COUNT(DISTINCT S.OrderPO) AS orders
FROM data_intra.yw1_ordersheet S
INNER JOIN data_intra.productdata P
ON P.productid = S.productid
WHERE P.eCode IN (
SELECT
eCode
FROM data_intra.productdata
WHERE productid = 1001
)
;

Related

How to select multiple MIN record of table that inner joinned with other 3 table based on other table parameter(s)?

I have a question. I have 4 tables:
product_list
product
product_img
pricelist
This what my query looks like:
SELECT
product_list.id,
product_list.class,
product.prod_name,
product.prod_url,
product.prod_overview,
product_img.list_prod340x340,
pricelist.price
FROM
(
(
(
product_list
INNER JOIN product ON product_list.id = product.prod_list_id
)
INNER JOIN product_img ON product.id = product_img.prod_id
)
INNER JOIN pricelist ON product.id = pricelist.prod_id
)
ORDER BY product_list.id, pricelist.price ASC
This is the result of the query
[QUERY RESULT]
[1]: https://i.stack.imgur.com/V9JO1.jpg
So the question is, how can i get only the lowest price of each prod_name.
This is how it should be returned
id
...
prod_name
...
...
...
price
1
...
Toyota Agya
...
...
...
155500000
2
...
Toyota Calya
...
...
...
151600000
please help?
Please test this:
SELECT product_list.id, product_list.class,
product.prod_name, product.prod_url,
product.prod_overview, product_img.list_prod340x340, MIN(pricelist.price)
FROM (((product_list
INNER JOIN product
ON product_list.id = product.prod_list_id)
INNER JOIN product_img
ON product.id = product_img.prod_id)
INNER JOIN pricelist
ON product.id = pricelist.prod_id)
GROUP BY product_list.id, product_list.class, product.prod_name, product.prod_url,product.prod_overview, product_img.list_prod340x340
ORDER BY product_list.id, pricelist.price ASC
The easiest approach is probably to get the price in a subquery:
SELECT
pl.id,
pl.class,
p.prod_name,
p.prod_url,
p.prod_overview,
pi.list_prod340x340,
(
SELECT MIN(price)
FROM pricelist prl
WHERE prl.price = p.id
) AS min_price
FROM product_list pl
INNER JOIN product p ON p.prod_list_id = pl.id
INNER JOIN product_img pi ON pi.prod_id = p.id
ORDER BY pl.id, p.id;
Since MySQL 8.0.14 you can move the subquery to the FROM clause and make this a lateral join, which allows you to select more than one column from the price table:
SELECT
pl.id,
pl.class,
p.prod_name,
p.prod_url,
p.prod_overview,
pi.list_prod340x340,
prli.price
FROM product_list pl
INNER JOIN product p ON p.prod_list_id = pl.id
INNER JOIN product_img pi ON pi.prod_id = p.id
CROSS JOIN LATERAL
(
SELECT *
FROM pricelist prl
WHERE prl.price = p.id
ORDER BY prl.price
LIMIT 1
) prli
ORDER BY pl.id, p.id;

How Can I Select needed information in SQL?

My BD:
I need to select the column with departament.nume which have <=3 records in tabel angajat.departament_id.
i tried:
SELECT departament.nume
FROM (angajat INNER JOIN
departament
ON angajat.departament_id=departament.id_dep
)
where count(angajat.id_dep)<=3;
Aggregate before joining:
SELECT d.nume
FROM departament d LEFT JOIN
(SELECT a.departament_id, COUNT(*) as cnt
FROM angajat a
GROUP BY a.departament_id
) a
ON a.departament_id = d.id_dep
WHERE COALESCE(cnt, 0) < 3 ;
Note the use of LEFT JOIN to be sure that departments with no rows in agnajat are included in the result set.
SELECT departament.nume
FROM angajat
INNER JOIN departament
ON angajat.departament_id=departament.id_dep
GROUP BY departament.nume
HAVING COUNT(*)<=3
Use Group By and Having
SELECT d.nume,
FROM angajat a JOIN departament d ON a.departament_id = d.id_dep
GROUP BY d.nume
HAVING COUNT (d.nume) <= 3;
No need for a subquery.
SELECT departament.nume
FROM departament
LEFT JOIN angajat ON angajat.departament_id=departament.id_dep
GROUP BY departament.id_dep
HAVING COUNT(*) <= 3
If you don't want departments with no angajat records, use an inner join instead.
If you want the counting to include together departments with the same nume but different id_dep, group on nume instead.
If you don't want that, but only want each nume returned only once, select DISTINCT departament.nume.

select sum qty from 2 tables

In MySQL I have 4 tables:
- product(id)
- order(id)
- order_detail_1(id, product_id, order_id, qty)
- order_detail_2(id, product_id, order_id, qty)
I want to get the sum of the quantity of products sold from the 2 tables (order_detail_1, order_detail_2) grouping them by product
produt can existe in order_detail_1 and not in order_detail_2 and vice versa
i tested this query and it worked but I want a simpler query without the union and the subquery.
select tmp.product_id ,sum(tmp.qty) from
(
(
select order_detail_1.product_id ,sum(order_detail_1.qty)
from order_detail_1
inner join order on order_detail_1.id_order = order.id
where order_detail_1.product_id is not null
group by order_detail_1.product_id
)
union all
(
select order_detail_2.product_id ,sum(order_detail_2.qty)
from order_detail_2
inner join order on order_detail_2.id_order = order.id
where order_detail_2.product_id is not null
group by order_detail_2.product_id
)
) tmp
group by tmp.product_id
It looks like you're not using order table other then checking if it exists, so you can use EXISTS()
SELECT p.product_id,sum(p.qty) as qty
FROM (SELECT product_id,qty,id_order FROM order_detail_1
WHERE product_id IS NOT NULL
UNION ALL
SELECT product_id,qty,id_order FROM order_detail_2
WHERE product_id IS NOT NULL) p
WHERE EXISTS(SELECT 1 FROM order o
WHERE o.id = p.id_order)
GROUP BY p.product_id
If a product is in only one table, you can use left join:
select p.id, (coalesce(sum(od1.qty), 0) + coalesce(sum(od2.qty, 0))) as qty
from product p left join
order_detail_1 od1
on od1.product_id = p.id left join
order_detail_2 od2
on od2.product_id = p.id
group by p.id;
This formulation depends on the fact that the two tables are exclusion -- a product is in only one table.
EDIT:
If products can exist in both tables, then you need to aggregate them first:
select p.id, (coalesce(od1.qty, 0) + coalesce(od2.qty, 0)) as qty
from product p left join
(select product_id, sum(qty) as qty
from order_detail_1 od1
group by product_id
) od1
on od1.product_id = p.id left join
(select product_id, sum(qty) as qty
from order_detail_2 od2
group by product_id
) od2
on od2.product_id = p.id;

inner join 4 tables with group, order by, having clause

I have 4 table and i want to extract: id, nume, localitate, masina_id, nr_inmatriculare, an_fabricatie, rafinarie, marca, and sum (quantity+deliver_quantity) as total_quantity group by an_fabricatie , Order by marca, and put some having clouse.
I don’t know how to make this.
My query is as bellow , but I think isn't correct.
select c.id, c.nume,c.localitate,l.masina_id, i.nr_inmatriculare, i.an_fabricatie,
i.rafinarie, m.marca from clienti c inner join livrari l on c.id = l.id inner join incarcari I on l.incarcare_id = l.livrari_id inner join masina m on i.id_marca = m.id, sum(select quantity, deliver_quantity) as total_quantity group by an_fabricatie having quantity >1000 order by marca;
Incarcari table
Id|livrari_id|id_marca|nr_inmatriculare|an_fabricatie|rafinarie|aviz_incarcare|quantity|
Livrari table
Id|masina_id|client_id|incarcare_id|deliver_quantity|aviz_livrare
Masini table
Id|numar_inmatriculare|marca|an_fabricatie|
Clienti table
Id|nume|localitate|date_add|date_upd|
SELECT c.id, c.nume, c.localitate, l.masina_id, i.nr_inmatriculare, i.an_fabricatie, i.rafinarie, m.marca, (SUM(i.quantity) + SUM(l.deliver_quantity)) AS total_quantity
FROM clienti c
INNER JOIN livrari l ON c.id = l.id
INNER JOIN incarcari i ON l.incarcare_id = i.livrari_id
INNER JOIN masini m ON i.id_marca = m.id
GROUP BY i.an_fabricatie, c.id, c.nume,c.localitate,l.masina_id, i.nr_inmatriculare, i.rafinarie, m.marca
HAVING i.quantity > 1000
ORDER BY m.marca DESC;

Count how many customers that they just have 1 order in MySQL

I'm using MySQL database server. My query is:
Count how many customers that they just have 1 order and how many customers that they have more than 1 orders.
This is my SQL query:
SELECT
COUNT((SELECT
customer_code
FROM
customer AS c
LEFT JOIN
order_info AS oi ON (c.customer_code = oi.customer_code)
GROUP BY customer_code
HAVING COUNT(id_order) = 1)) AS New_customers
How can I get this result.
You are grouping by customer_code before counting, I think this will group the rows together thus effectively removing all orders from the resultset. HAVING will always use the result set as the 'data feed'.
SELECT
COUNT(DISTINCT customer_code)
FROM
customer AS c
LEFT JOIN order_info AS oi ON (c.customer_code = oi.customer_code)
HAVING COUNT(id_order) = 1
OR a lot simpler (but perhaps not more efficient)
SELECT
COUNT(customer_code)
FROM
customer AS c
WHERE (
SELECT
COUNT(*)
FROM `order_info`
WHERE
`customer_code` = `c`.`customer_code`
) = 1
To get the number of customers with more than one order, simply change the = into > where appropiate.
SELECT
count(customer_code)
FROM
customer AS c
LEFT JOIN
order_info AS oi ON (c.customer_code = oi.customer_code)
GROUP BY customer_code
HAVING COUNT(id_order) = 1
For customers having 1 order
SELECT count(customer_code) FROM customer AS c
INNER JOIN order_info AS oi ON (c.customer_code = oi.customer_code)
GROUP BY customer_code HAVING COUNT(id_order) = 1))
For customers having MORE THAn 1 order
SELECT count(customer_code) FROM customer AS c
INNER JOIN order_info AS oi ON (c.customer_code = oi.customer_code)
GROUP BY customer_code HAVING COUNT(id_order) > 1))
Try this
SELECT
count(*)
FROM
customer AS c
LEFT JOIN
order_info AS oi ON c.customer_code = oi.customer_code
HAVING COUNT(id_order) = 1
try this:
SELECT * FROM ( select c.customer_code, count(*) total FROM customer c
LEFT JOIN
order_info AS oi ON (c.customer_code = oi.customer_code)
GROUP BY customer_code) test
CASE total
WHEN 1 THEN SELECT total one_order FROM test;
ELSE
SELECT total more_order FROM test