select values missing from one table based upon values in another table - mysql

I am using mysql and have 2 tables
table1
id
324
325
328
350
420
650
850
950
table2
id mapping_id
324 1
325 2
328 3
350 4
420 5
650 1
850 2
I want to produce a list of all the DISTINCT field mapping_ids that are missing for the ids in table one. For example id 850 has a mapping_id of 2 so is missing 1,3,4,5 and id 950 is not even in table 2 and so is missing 1,2,3,4,5. This should give me a distinct list of 1,2,3,4,5.
I have tried various LEFT JOIN queries but cannot get the results I need. Thanks in advance.

You could build a matrix of id - mapping combinations using a cross join. A not in subquery can determine which parts of the matrix are empty:
select *
from table1 t1
cross join
(
select distinct mapping_id
from table2
) mappings
where not exists
(
select *
from table2 t2
where t2.id = t1.id
and t2.mapping_id = mappings.mapping_id
)

select t1.id, t2.mapping_id
from table1 t1, table2 t2
MINUS
select t2.id, t2.mapping_id
from table1 t1
inner join table2 t2 on t1.id = t2.id

Related

Left join with other table with where clause

I have 2 tables in MySQL database that I would like to join, where I would like to contain all results from table1.
My tables looks like this:
table1
id
name
1
name1
2
name2
3
name3
4
name4
5
name5
6
name6
7
name7
8
name8
table2
id
table1_id
myfield
1
3
test1
2
2
test2
3
1
test1
4
4
test2
5
5
null
6
2
null
What I am trying to achieve is to get a table which contains all the rows from table1 and only the data that is joined from table2.
This is my query:
select * from table1 as t1
left join table2 as t2 on t1.id = t2.table1_id
where myfield="test1"
group by t1.id
But this is not what I want to achieve.
What I want to achieve is to get all records from table1 and to have all related records from table2 where table2.myfield="test1". And for the other for table2.mytable to have null (if they do not fulfil table2.myfield="test1").
Any help is much appreciated!
Thanks!
move the where clause to the on clause:
select * from table1 as t1
left join table2 as t2 on t1.id = t2.table1_id
and myfield="test1"
group by t1.id
BTW: some DBMS does not allow select * with group by. So select the id and some aggregated values or remove group by id

Select All from one table and fill values from another table on the result

I want get full column from one table and select sum from another table that have same id.
Eg:
table1 table2
id target id target achived
1 40 1 20
2 50 2 25
3 66
4 80
and i want to select all from table 1 and fill achived target results on it.
Eg:
id target target achived
1 40 20
2 50 25
3 66 0
4 80 0
how can i do that using mysql
Use this query:
select table1.*, case when table2.target_achieved is null
then 0
else table2.target_achieved
end as target_achieved
from table1 left join table2
on table1.id = table2.id
order by table1.id
Below query results in 0 instead of NULL
SELECT t1.id, target, COALESCE(target_achieved, 0) AS target_achieved
FROM table1 AS t1
LEFT JOIN table2 AS t2
ON t1.id = t2.id;

Delete rows with duplicated/repeated data in specified columns

I need To Delete Repeated Records (only if cod1 and Model are repeated) And Save only one of thats.
ID Cod1 Model
1 332 mdl1
2 332 mdl1
3 332 mdl2
4 450 mdl2
5 450 mdl2
The output must Be
ID Cod1 Model
1 332 mdl1
3 332 mdl2
4 450 mdl2
Really Thanks!
try this one. Replace occurrences of Table1 with your actual table name.
DELETE FROM Table1 WHERE ID IN
(SELECT * FROM
(SELECT T2.Id
FROM Table1 T1
INNER JOIN Table1 T2
ON T1.Cod1 = T2.Cod1 AND T1.Model = T2.Model
WHERE T2.ID > T1.ID
)T
);
sqlfiddle
In the inner most query, T1 will find matching T2 records when Cod1 and Model match and T2.Id will be the larger id. So it returns IDs of rows to be deleted. But Mysql doesn't allow you to delete from a query that is from the same table so we have to wrap that inside another SELECT statement to trick Mysql into letting you do it. And that's it.

Mysql left join fails to returns all values from first table

I've two tables named table1 and table2. table2 may have elements from table1. I'd like to show all the results from table2 with the price if available in table1 and with status 1. If no product matches in table1 and also status is 0, need to return price as 0.
table1
id pname item_code price status
1 product1 abcd 200 1
2 product2 pqrs 500 1
3 product3 wxyz 425 1
4 product5 mnop 100 0
and table2 as follows
id item_code
10 efgh
11 abcd
12 pqrs
13 mnop
I have tried following query
SELECT `t2`.`id`, `t2`.`item_code`, `t1`.`price`,`t1`.`pname`, COUNT(t2.item_code) AS sellers FROM (`table2` as t2) LEFT JOIN `table1` as t1 ON `t1`.`item_code` = `t2`.`item_code` WHERE `t1`.`status` = 1 GROUP BY `t2`.`item_code`
but it returns common values in table1 and table2 with status 1, but I need all records from table2 with price as 0 if nothing match in table1 or status 0 in table1.
Expected output
id item_code price
10 efgh 0
11 abcd 200
12 pqrs 500
13 mnop 0
Any help please.
Thanks,
Not sure about your current query which is having count and group by however you can do as below
select
t2.id,
t2.item_code,
case
when t1.status = 1 then t1.price
else 0
end as price
from table2 t2
left join table1 t1 on t1.item_code = t2.item_code
Now note that if table1 has multiple matching values from table2 in that case we may need grouping data.
Try below query:
SELECT `t2`.`id`, `t2`.`item_code`, `t1`.`price`,`t1`.`pname`, COUNT(t2.item_code) AS sellers FROM (`table2` as t2) LEFT JOIN (select * from table1 where status = 1)t1 ON `t1`.`item_code` = `t2`.`item_code` GROUP BY `t2`.`item_code`
Move the part of the WHERE clause that checks the left joined table to the ON clause
SELECT `t2`.`id`, `t2`.`item_code`, COALESCE(`t1`.`price`, 0),`t1`.`pname`, COUNT(t2.item_code) AS sellers
FROM (`table2` as t2)
LEFT JOIN `table1` as t1
ON `t1`.`item_code` = `t2`.`item_code`
AND`t1`.`status` = 1
GROUP BY `t2`.`item_code`

SQL Query to join Two tables

I have two table as follows :-
table1 table2
date time amount date time amount
20120101 1000 101 20120104 1000 10
20120101 1100 100 20120104 1100 11
20120104 1000 101 20120105 1000 11
20120104 1100 105 20120105 1100 8
I want to join these two tables to get the output as follows :
date time table1-amt table2-amt
20120101 1000 101 NULL
20120101 1100 100 NULL
20120104 1000 101 10
20120104 1100 105 11
20120105 1000 NULL 11
20120105 1100 NULL 8
What is the sql query to get this output? I am using mysql database.
I tried following query:
select table1.date,table1.time,table1.close , table2.close
from table1,
table2
where table1.date=table2.date
and table1.time=table2.time;
it gave me output as
date time amount amount
20120104 1000 101 10
20120104 1100 105 11
People are directing me towards left outer join , full outer join I tried following two queries which did nt solve my purpose .
select * from table1 left join table2 on table1.date=table2.date ;
select * from table1 left join table2 on table1.date=table2.date union select * from table1 right join table2 on table1.date=table2.date;
An approach that only involves reading from each of the tables once:
SELECT `date`, `time`, sum(`amt1`) as `table1-amt`, sum(`amt2`) as `table2-amt`
FROM
(SELECT `date`, `time`, amount as amt1, null as amt2
FROM Table1
UNION ALL
SELECT `date`, `time`, null as am1, amount as amt2
FROM Table2) v
GROUP BY `date`, `time`
(As opposed to the examples linked in Yordi's answer, which each read from each table twice.)
This is what you want
Full Outer Join in MySQL
Not going to just give the answer, you'll find i there and learn some.
EDIT : Oh well someone beat me to it, and just handed it to you ^^.
You need a FULL (outer) JOIN. One way to achieve it in MySQL:
SELECT t1.date, t1.time, t1.close AS table1_amt, t2.close AS table2_amt
FROM table1 AS t1
LEFT JOIN table2 AS t2
ON t1.date = t2.date
AND t1.time = t2.time
UNION ALL
SELECT t2.date, t2.time, t1.close, t2.close
FROM table1 AS t1
RIGHT JOIN table2 AS t2
ON t1.date = t2.date
AND t1.time = t2.time
WHERE t1.date IS NULL ;