How to write query for left join - mysql

i have written left join query and i want the product_code column of left table should be updated by the product_code column of right table by the condition of below query
update stock_details_mt as s left join
(select min(product_code),product_name,mrp,sales_rate from stock_details_mt group by product_name,mrp,sales_rate having count(*)>1)as s2 set
s.product_code=s2.product_code on s.product_name=s2.product_name where s.mrp=s2.mrp and s.sales_rate=s2.sales_rate ;

You seem to have lost the plot between the join and set and I would be suspicious of the left join. Try this.
update stock_details_mt as s join
(select min(product_code) product_code,product_name,mrp,sales_rate
from stock_details_mt
group by product_name,mrp,sales_rate
having count(*)>1) as s2
on s.product_name=s2.product_name and s.mrp=s2.mrp and s.sales_rate=s2.sales_rate
set s.product_code=s2.product_code
where 1 = 1;
So given
drop table if exists stock_details_mt;
create table stock_details_mt
(product_code int, product_name varchar(10), mrp int, sales_rate int);
insert into stock_details_mt values
(2,'aaa',1,1),(1,'aaa',1,1),(10,'aaa',1,1),
(10,'bbb',1,1);
Result
+--------------+--------------+------+------------+
| product_code | product_name | mrp | sales_rate |
+--------------+--------------+------+------------+
| 1 | aaa | 1 | 1 |
| 1 | aaa | 1 | 1 |
| 1 | aaa | 1 | 1 |
| 10 | bbb | 1 | 1 |
+--------------+--------------+------+------------+
4 rows in set (0.00 sec)

Related

A join or function in Mysql to include all unique items of one column and all unique items of second column

I need to combine the unique values of one column and the unique values of another column as one new column. As shown in Table example 2
Union to append all DISTINCT return dates
drop table if exists t;
create table t
(cid int, bid int,cdate varchar(6),rdate varchar(6));
insert into t values
(103,23,'15-mar','26-jan'),
(103,23,'14-apr','26-jan'),
(103,23,'18-may','26-jan');
select cid,bid,cdate,rdate,cdate as newdate from t
union all
(select distinct cid,bid,null,null,rdate from t)
;
+------+------+--------+--------+---------+
| cid | bid | cdate | rdate | newdate |
+------+------+--------+--------+---------+
| 103 | 23 | 15-mar | 26-jan | 15-mar |
| 103 | 23 | 14-apr | 26-jan | 14-apr |
| 103 | 23 | 18-may | 26-jan | 18-may |
| 103 | 23 | NULL | NULL | 26-jan |
+------+------+--------+--------+---------+
4 rows in set (0.002 sec)
select column1,column2,count(column1) as c1 ,count(column2) as c2 from MyTable having c1 =1 OR c2 =1

Percentage calculus based on multiple tables in sql

I have two tables in sql and I need to create another table performing the calculations based on two other tables.
The first one has the sum of revenue for each Ad Unit, table name is ad_unit_table
SELECT
d.`Date`,
'App' as `Partner`,
d.`Ad Unit`,
sum(d.`Revenue`) as `Revenue`
from
`d_master` as d
group by
`Ad Unit`, `Date`
The other table has the sum of revenue for ALL Ad Units, table name is sum_revenue
SELECT
`Date`,
`Partner`
`Ad Unit`,
sum(`Revenue`) as `Sum Revenue`
from
`ad_unit_table`
group by
`Date`
Now I have to find the percentage of the revenue for each Ad Unit. So the formula is (Ad Unit Rev / Sum Rev) * 100. My code currently looks like this:
SELECT
ad.`Date`,
ad.`Partner`,
ad.`Ad Unit`,
(ad.`Revenue` / s.`Sum Revenue`) * 100 as `Percentage`
FROM
`ad_unit_table` as ad
LEFT JOIN `sum_revenue` as s ON ad.`Partner`
GROUP BY
`Date`,
`Ad Unit`
It gives me all NULLS. I would appreciate any help. Thank you!
Are you sure you want to do LEFT JOIN sum_revenue as s ON ad.Partner in your last query?. I tested this construct and this creates a so called cartesian product.
All rows of the left table are combined with all the rows from the other table.
See: https://en.wikipedia.org/wiki/Cartesian_product
For example:
create table testing.test_a (id INT);
create table testing.test_b (id INT);
INSERT INTO test_a VALUES(1),(2),(3),(4);
INSERT INTO test_b VALUES(1),(2),(3),(5);
# Resulting in a cartesian product (4x4 entries)
SELECT * FROM test_a AS a LEFT JOIN test_b AS b ON a.id;
+------+------+
| id | id |
+------+------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
| 1 | 2 |
| 2 | 2 |
| 3 | 2 |
| 4 | 2 |
| 1 | 3 |
| 2 | 3 |
| 3 | 3 |
| 4 | 3 |
| 1 | 5 |
| 2 | 5 |
| 3 | 5 |
| 4 | 5 |
+------+------+
# Correctly LEFT joining test_a and test_b would be:
SELECT a.id, b.id FROM test_a AS a LEFT JOIN test_b AS b ON a.id = b.id
# Or use the USING clause to join on column from both tables with same name.
SELECT test_a.id, test_b.id FROM test_a LEFT JOIN test_b USING(id);
+------+------+
| id | id |
+------+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | NULL |
+------+------+
Are you sure the table sum_revenue has entries for all units in ad_unit_table. If this is not the case, some values from sum_revenue result in NULL values because of the not matching entries.
If you only want the values that match use an INNER JOIN instead of an LEFT JOIN.
Also make sure that when could the calculations. none of the values are NULL. Doing calculating with NULL values results in NULL values.
Example:
SELECT 100 / NULL; -- Result NULL
SELECT (10 * NULL) * 100; -- Result NULL
Without more information like table definitions and/or sample data this is all that I can do.

How to join with table that have no record?

I have this two table products and wishlist. Here is the structure
And here is wishlist
Here is my query
SELECT a.productId,productName,isNew,isHot,productImage,a.categoryId,productPrice,productDescription,
IF(b.UserId = NULL, 1,0) as isLiked
from products a LEFT JOIN wishlist b on (a.productId = b.productId) and (a.categoryId = b.categoryId)
where b.userId = 'usr001'
But the the query is not showing any records, when I delete the condition it showing the records of products.
So I want to showing the records of product even using the condition, how can I fix it?
This works as expected
Products
+----+-----------+
| id | name |
+----+-----------+
| 1 | product 1 |
| 2 | product 2 |
| 3 | product 3 |
| 4 | product 4 |
| 5 | product 5 |
+----+-----------+
5 rows in set (0.00 sec)
create table wishlist
(userid int, productid int,name varchar(20));
insert into wishlist values
(1,1,'product 1'),
(1,3,'product 3');
select p.id,p.name,if(w.productid is null, 0 , 1 ) isliked
from products p
left join wishlist w on w.productid = p.id and p.name = w.name and w.userid = 1
order by p.id limit 5;
+----+-----------+---------+
| id | name | isliked |
+----+-----------+---------+
| 1 | product 1 | 1 |
| 2 | product 2 | 0 |
| 3 | product 3 | 1 |
| 4 | product 4 | 0 |
| 5 | product 5 | 0 |
+----+-----------+---------+
5 rows in set (0.00 sec)
I don't see a difference between my model and yours - It would help if you added sample data as text to the question together with the table defintions(as text).
Use b.userId = 'usr001' in ON Clause instead of where clause
SELECT a.productId,productName,isNew,isHot,productImage,a.categoryId,productPrice,productDescription,
IF(b.UserId is NULL, 1,0) as isLiked
from products a LEFT JOIN wishlist b on (a.productId = b.productId) and (a.categoryId = b.categoryId)
and b.userId = 'usr001'

Multiple times values are coming in mysql

I have two tables
tbl1 and tbl2
tbl1 table contains 5 columns name id(pk), email , address ,pid(INDEX),status(ENUM Y,N)
tbl2 table contains 3 columns id(pk) ,pid(INDEX),domain
When i am running this query
SELECT *
FROM tbl1 as l
LEFT JOIN tbl2 as m on l.pid=m.pid
WHERE l.status='Y';
It is giving multiple records . Please note we are making join in pid both pid are not primary key. Please help to get only unique values from both table.
enter image description here
You seem to want to join on the basis of relative position in the tables.A way to do this is row_number simulation using variables.
drop table if exists t1,t2;
create table t1(id int, email varchar(5),address varchar(10),pid int,status varchar(1));
create table t2(id int, pid int, domain varchar(5));
insert into t1 values (1,'aa#aa', 'aaaaa',428,'Y'), (2,'bb#bb', 'bbbbb',428,'n'),(3,'cc#cc', 'ccccc',428,'Y') ;
insert into t2 values (1,428,'mmm'),(2,428,'zzz');
select t1.*,t2.*
from
(
select t1.*,
if(t1.pid <> #pid1, #bn1:=#bn1+1,#bn1:=#bn1) BlockNo1,
if(t1.id <> #id1, #rn1:=#rn1+1, #rn1:=1) rowno1,
#pid1:=t1.pid pid1,
#id1:=t1.id p1
from t1
cross join (select #bn1:=0,#rn1:=0, #pid1:=0 ,#id1:=0) r
where status = 'y'
order by t1.pid,t1.id
) t1
join
(
select t2.id t2id,t2.pid t2pid, t2.domain t2domain,
if(t2.pid <> #pid2, #bn2:=#bn2+1,#bn2:=#bn2) BlockNo2,
if(t2.id <> #id2, #rn2:=#rn2+1, #rn2:=1) rowno2,
#pid2:=t2.pid pid2,
#id2:=t2.id p2
from t2
cross join (select #bn2:=0,#rn2:=0, #pid2:=0 ,#id2:=0) r
order by t2.pid,t2.id
) t2 on (t1.blockno1 = t2.blockno2) and (t1.rowno1 = t2.rowno2)
+------+-------+---------+------+--------+----------+--------+------+------+------+-------+----------+----------+--------+------+------+
| id | email | address | pid | status | BlockNo1 | rowno1 | pid1 | p1 | t2id | t2pid | t2domain | BlockNo2 | rowno2 | pid2 | p2 |
+------+-------+---------+------+--------+----------+--------+------+------+------+-------+----------+----------+--------+------+------+
| 1 | aa#aa | aaaaa | 428 | Y | 1 | 1 | 428 | 1 | 1 | 428 | mmm | 1 | 1 | 428 | 1 |
| 3 | cc#cc | ccccc | 428 | Y | 1 | 2 | 428 | 3 | 2 | 428 | zzz | 1 | 2 | 428 | 2 |
+------+-------+---------+------+--------+----------+--------+------+------+------+-------+----------+----------+--------+------+------+
2 rows in set (0.04 sec)

Get records from one table and a corresponding table

I have two tables:
orders
poid | user | pid | payment_id
1 | 1 | 1 | abc123
2 | 2 | 2 | def345
orders_addon
poaid | user | poid | pid
1 | 1 | 1 | 3
2 | 1 | 1 | 5
One represents orders, the second one represent addons a user can add to his order.
There is always a row in orders and it can occur that there is no matching orders_addon for an order.
I'm looking for a query that returns matching rows from orders and orders_addon if there are matching ones.
SELECT user,pid FROM ... WHERE payment_id = 'abc123'
Should return
user | pid
1 | 1
1 | 3
1 | 5
And the same query should only return results from the orders table if there is no matching record in the orders_addon table.
SELECT user,pid FROM ... WHERE payment_id = 'def345'
user | pid
2 | 2
I reckon this could be done using UNION but then I wouldn't be able to match the tables and it would become a problem since the orders_addon table doesn't have a payment_id
Use LEFT JOIN WITH IF STATMENT
mysql> ( SELECT u.user,IFNULL(ua.pid ,u.pid) as pid
FROM orders u
inner JOIN orders_addon ua on ua.poid=u.poid
WHERE u.payment_id = 'abc123'
)
union all
( SELECT u.user,u.pid
from orders u
where u.payment_id = 'def345'
);
+------+------+
| user | pid |
+------+------+
| 1 | 3 |
| 1 | 5 |
| 2 | 2 |
+------+------+
3 rows in set (0.00 sec)
mysql> ( SELECT u.user,IFNULL(ua.pid ,u.pid) as pid
FROM orders u
inner JOIN orders_addon ua on ua.poid=u.poid
WHERE u.payment_id = 'def345'
)
union all
( SELECT u.user,u.pid
from orders u
where u.payment_id = 'def345'
);
+------+------+
| user | pid |
+------+------+
| 2 | 2 |
+------+------+
1 row in set (0.00 sec)