Sub query with no result - mysql

I have two query that I would like to combine into one.
Query 1: SELECT Quantity FROM Table1 WHERE IdProduct = 1234
Query 2: SELECT Supplier FROM Table2 WHERE IdProduct = 1234
Here is what I have done:
SELECT
bloc1.Quantity AS qty,
bloc2.Supplier AS supplier
FROM
(SELECT Quantity FROM Table1 WHERE IdProduct = 1234) bloc1,
(SELECT Supplier FROM Table2 WHERE IdProduct = 1234) bloc2
Most of the time everything goes well, but unfortunately, sometimes one of the two query return no result... In this specific case, the two query "fail".

U can join the two tables table1 and table2 u can do:
SELECT qty,sup
FROM (SELECT Quantity as qty,supplier as sup
FROM Table1
INNER JOIN Table2
ON table1.IdProduct=table2.IdProduct AND IdProduct=1234);
u can check this for more information on joins in mysql https://www.mysqltutorial.org/mysql-join/

Your code is doing a CROSS JOIN of the results of the 2 queries.
So if any of them returns no rows, the result is no rows.
Instead use the result of the 2 queries as columns if you are sure that they will return only 1 row:
SELECT
(SELECT Quantity FROM Table1 WHERE IdProduct = 1234) qty,
(SELECT Supplier FROM Table2 WHERE IdProduct = 1234) supplier

It's remarkable to me that slapping those queries together like that ever works. But if you want it to survive a lack of records in one of these tables, you'll need an OUTER JOIN of some kind. See https://dev.mysql.com/doc/refman/5.7/en/join.html.

You probably want a "full outer join". Unfortunately MySQL does not implement full outer joins (why in this day and age?).
Anyway, you can simulate it with the workaround:
SELECT
bloc1.Quantity AS qty,
bloc2.Supplier AS supplier
FROM (SELECT Quantity FROM Table1 WHERE IdProduct = 1234) bloc1
LEFT JOIN (SELECT Supplier FROM Table2 WHERE IdProduct = 1234) bloc2 on 1 = 1
UNION
SELECT
bloc1.Quantity AS qty,
bloc2.Supplier AS supplier
FROM (SELECT Quantity FROM Table1 WHERE IdProduct = 1234) bloc1
RIGHT JOIN (SELECT Supplier FROM Table2 WHERE IdProduct = 1234) bloc2 on 1 = 1
In MySQL 8.x you can remove the redundancy (and somewhat shorten it) by using CTEs. For example:
with
bloc1 as (SELECT Quantity FROM Table1 WHERE IdProduct = 1234),
bloc2 as (SELECT Supplier FROM Table2 WHERE IdProduct = 1234)
SELECT
bloc1.Quantity AS qty,
bloc2.Supplier AS supplier
FROM bloc1 LEFT JOIN bloc2 on 1 = 1
UNION
SELECT
bloc1.Quantity AS qty,
bloc2.Supplier AS supplier
FROM bloc1 RIGHT JOIN bloc2 on 1 = 1

You can try the below -
select
(SELECT Quantity FROM Table1 WHERE IdProduct = 1234) as qty,
(SELECT Supplier FROM Table2 WHERE IdProduct = 1234) as supplier

Related

mySQL - SUM of column

I have 2 tables
table 1
id product
1 P1
2 P2
table 2
id amount product_t1
1 100 P1
2 200 P1
3 300 P2
4 400 P1
5 500 P2
I want my output to be:
product totalAmount(sum of amount)
P1 700
P2 800
EDIT: Here is my query so far
SELECT T1.product, SUM(T2.amount)
FROM table1 T1
INNER JOIN table2 T2
ON T1.product = T2.product_t1
Thanks!
you should use group by
SELECT T1.product, SUM(T2.amount)
FROM table1 T1
INNER JOIN table2 T2
ON T1.product = T2.product_t1
GROUP BY product
Since you're not using foreign keys you don't even need the table 1 for the desired result.
SELECT
product_t1 AS product,
SUM(amount) AS totalAmount
FROM table2
GROUP BY product_t1
What you're missing is the GROUP BY statement in order to get a separate row for each individual product
SELECT T1.product, SUM(T2.amount)
FROM table1 T1
INNER JOIN table2 T2
ON T1.product = T2.product_t1
GROUP BY product T1.product
Use the GROUP BY tag . Group by helps to group your result via value of product
Try to play with GROUP BY and AS
SELECT product_t1 as product, SUM(amount) AS totalAmount FROM table2
GROUP BY product
https://dev.mysql.com/doc/refman/5.7/en/group-by-modifiers.html
OR add to your code group by
SELECT T1.product, SUM(T2.amount)
FROM table1 T1
INNER JOIN table2 T2 ONT1.product = T2.product_t1
Gruop by T1.product

SQL query to find comparision between different products

Hi i am a newbie to SQL and have one doubt on comparing different products across multiple tables.
I have 3 tables
T1:
Product_type
order_id
T2 and T3 also has the same fields.
All the tables have different product types. They may or may not have same order ids. Its like you can order product p1 from T1 and product p2 from T2 together on the same order id o1 or they can be separate orders.
I want to find the number of orders where product type(p1) from T1 and product type(p2) from T2 are ordered in the same order(having the same order id).
I am trying to run the query like this :
select COUNT(DISTINCT order_id) as CountOf from
(
select product_type from t1
UNION ALL select product_type from t2
)
AS m
where t1.product_type = p1 and t2.product_type = p2;
What i figured out is that i cannot access t1 and t2 in the outer query since they are used in the inner query. So is there a way i can make comparision between products?
Any help would be greatly appreciated.
Thank you
Try this:
select
count(distinct t1.order_id) as OrderCount
from
t1
inner join
t2 on t1.order_id = t2.order_id
where
t1.product_type = 'p1' and
t2.product_type = 'p2'
I can't understand what you want.
But inner query scope to brackets only. So you can not access outside to brackets. try to this
select COUNT(DISTINCT order_id) as CountOf from
(
select DISTINCT order_id from t1
where t1.product_type = p1
UNION ALL
select DISTINCT order_id from t2
where t2.product_type = p2
) m

SQL join table to selected records

Example:
SELECT SUM(SALARY) FROM (SELECT * FROM table1 WHERE id > 10) a LEFT JOIN table2 b on a.person = b.person
I want join table2 records only to (SELECT * FROM table1 WHERE id > 10) records, my example is not correct.
table1 contain 100mln records and I cant join table2 to all records I must use subquery
I'm assuming, you salary is not summing up correctly (you are getting more than you expect). This is because LEFT JOIN will leave NULL for the rowsthat doesn't have match in b.
For this SQL:
SELECT a.*, b.*
FROM (select * from (SELECT 123 AS Salary,
'Tom' AS person
UNION
SELECT 343 AS Salary,
'Bob' AS person
UNION
SELECT 877 AS Salary,
'Tom' AS person) as t where t.Salary > 123) a
LEFT JOIN (SELECT *
FROM (SELECT 'Tom' AS person,
1 AS id
UNION
SELECT 'Bob' AS person,
2 AS id) AS t
WHERE t.id = 1) AS b
ON a.person = b.person
you will have this output:
So INNER JOIN should work for you.
SELECT SUM(SALARY) FROM (SELECT * FROM table1 WHERE id > 10) a
LEFT JOIN table2 b on a.person = b.person
Hopefully this will get you going in the correct direction....
select sum(a.salary)
from table1 a
left join table2 b on a.person = b.person and b.salary_type = "something"
where a.id > 10
;

Complex MySQL query using group by

Lets say i have two tables
Table1:
product_id, design1, design2
1 A C
2 B A
Table2:
product_id, value
1 10
2 10
Now i want to to sum all the value for particular design for all products.
SELECT designA, SUM(value) FROM (
SELECT b.design1 AS designA, SUM(value) AS value FROM table2 AS a LEFT JOIN table1 AS b ON a.product_id = b.product_id GROUP BY b.design1) AS T GROUP BY designA
It gives me this:
designA SUM(value)
A 10
B 10
Now the problem is that if user has specified design2 in table1 then what ever is the value of design1 will automatically be added in design2. If design2 is not present design1 column then it will be a new row of result:
Desited result is this:
designA SUM(value)
A 20
B 10
C 10
select y.designA, sum(value) from
(select a.design1 as designA, value from
Table1 as a
inner join Table2 as b
on
a.product_id = b.product_id
union all
select a.design2 as designA, value from
Table1 as a
inner join Table2 as b
on
a.product_id = b.product_id) as y
group by y.designA
seems to work for your test data, not tried on other configurations but you should be able to tweak it, if you understand what it's doing.
UNION in the matches based on design2:
SELECT designA, SUM(value) FROM (
SELECT b.design1 AS designA, SUM(value) AS value FROM table2 AS a LEFT JOIN table1 AS b ON a.product_id = b.product_id GROUP BY b.design1
UNION
SELECT b.design2 AS designA, SUM(value) AS value FROM table2 AS a LEFT JOIN table1 AS b ON a.product_id = b.product_id GROUP BY b.design2
) AS T GROUP BY designA

mysql left join duplicate my table rows - why?

I have 2 tables:
Table1 => product_id, product_quantity => here I have 25 rows.
Table2 => product_hashid, order_quantity => here I have 1 query row.
I build this mysql query:
SELECT SUM(table1.product_quantity) - SUM(order_quantity) AS instocks
FROM table1 -- table.1 in original
LEFT JOIN table2 ON table2.product_hashid = table1.product_id
WHERE table1.product_id = '$thisid'
This query duplicates table2 row with table1. Is there some error in this query?
First, I want to sum all product_quantity from table1 where product_id = '$this' and sum all order_quantity in table2 where product_hashid = '$this' and make (a - b) to display a final result.
Your outline of what you want to do is good, but it isn't what you implemented.
I want to sum all product_quantity from table1 where product_id = '$this' and sum all order_quantity in table2 where product_hashid = '$this' and make (a - b) to display a final result.
Build it up one step at a time.
SELECT SUM(product_quantity) FROM Table1 WHERE Product_ID = '$this';
SELECT SUM(order_quantity) FROM Table2 WHERE Product_HashID = '$this';
SELECT (SELECT SUM(product_quantity) FROM Table1 WHERE Product_ID = '$this') -
(SELECT SUM(order_quantity) FROM Table2 WHERE Product_HashID = '$this')
FROM Dual;
You might observe that the code alignment emphasizes the inconsistent column naming for the product ID columns.
In the more general case:
SELECT Product_ID, SUM(product_quantity) AS Product_Quantity
FROM Table1
GROUP BY Product_ID;
SELECT Product_HashID AS Product_ID, SUM(order_quantity) AS Order_Quantity
FROM Table2
GROUP BY Product_HashID;
SELECT p.Product_ID, p.Product_Quantity - o.Order_Quantity AS SurplusOnHand
FROM (SELECT Product_ID, SUM(product_quantity) AS Product_Quantity
FROM Table1
GROUP BY Product_ID) AS P
JOIN (SELECT Product_HashID AS Product_ID, SUM(order_quantity) AS Order_Quantity
FROM Table2
GROUP BY Product_HashID) AS O
ON O.Product_ID = P.Product_ID;
Sometimes you need to use a LEFT OUTER JOIN; mostly, you don't. Write your SQL assuming you don't until you're sure that you do.
Given the data cardinalities (row counts), you may need to do an LOJ here. You need to manufacture a zero for the order quantity of those products listed in Table1 that are not listed in Table2.
SELECT (SELECT SUM(product_quantity) FROM Table1 WHERE Product_ID = '$this') -
NVL(SELECT SUM(order_quantity) FROM Table2 WHERE Product_HashID = '$this'), 0)
FROM Dual;
SELECT p.Product_ID, p.Product_Quantity - NVL(o.Order_Quantity, 0) AS SurplusOnHand
FROM (SELECT Product_ID, SUM(product_quantity) AS Product_Quantity
FROM Table1
GROUP BY Product_ID) AS P
LEFT OUTER JOIN
(SELECT Product_HashID AS Product_ID, SUM(order_quantity) AS Order_Quantity
FROM Table2
GROUP BY Product_HashID) AS O
ON O.Product_ID = P.Product_ID;
LEFT JOIN will return all of table1 in every case.
http://www.w3schools.com/sql/sql_join_left.asp
Do you actually want just the products in table1 if they appear in table 2? If so, you need simply JOIN (or INNER JOIN)
http://www.w3schools.com/sql/sql_join_inner.asp
I think the issue is your JOIN and your WHERE clause. In this setup, you will return all of the data from table2, which will give you a mess. Your WHERE clause is looking at table1 and limiting the rows there but your JOIN returns all rows from table2 and only those rows from table1 that are equal.
Bottom line: change your join to be an INNER JOIN and your problems will go away.