I have two tables in a database
Table1
T1ID
T1Value
1
T1V1
2
T1V2
3
T1V3
4
T1V4
Table 2
T2ID
T1FK
T2Value
1
2
T2V1
2
3
T2V2
Please note that Table2 has a foreign key, that references T1ID in Table1. Also note that not all entries in Table1 have corresponding entries in Table2.
Now, I would like to use a SINGLE SQL statement to do both of the two following
If there are corresponding entries in Table2 related to Table1, then run the following statement
SELECT t1.*, t2.T2Value FROM Table1 AS t1 INNER JOIN Table2 AS t2 ON t1.T1ID = t2.T1FK WHERE t1.T1ID = 2
If there aren't any corresponding entries in Table2 related to Table1, then run the following statement (notice that NULL is returned instaed of t2.T2Value)
SELECT t1.*, NULL FROM Table1 AS t1 WHERE t1.T1ID = 4
(Please note that t1.T1ID is supplied by the program, so this value will change. I am just showing you what I need)
How do I combine both the above statements into a single statement?
Thanks.
A simple LEFT JOIN will do what you want. For example:
select t1.*, t2.t2value
from table1 t1
left join table2 t2 on t1.t1id = t2.t1fk
where t1.t1id = <parameter>
For example:
If the parameter is 2, then a related row is found and the query returns the value of it (t2.t2value).
If the parameter is 4, then no related row is found and the query returns NULL in its place.
Related
I have 3 tables like this
With the tables filled like this:
How do I search the cases In where on the table 3 the idtable 1 has all the id from table 2 related?
For example idtable1 = 1 would be an output of that query cuz is related with every id from idtable2
Presumably, you intend:
select t1.*
from table1 t1
where (select count(*) from table3 t3 where t3.idtable1 = t1.idtable1) =
(select count(*) from table2);
This shows all records from table1 where table3 contains all values of idtable2 -- assuming no duplicates in table3 (and that the ids are unique).
I have a table which contains unique names, call it table1. I have another table which contains the same names but each name occurs several times, call it table2. Now, I want to copy data from table2 to table1 corresponding to the names. And if table2 has multiple records by the same name, I want the corresponding new records to be created in table1.
TABLE1 TABLE2
NAME NAME
A A
B A
C B
D B
Following the little chat int he comments, you could try this:
UPDATE t1
set columnx = t2.columnx
FROM table1 t1
LEFT JOIN table2 t2 on t2.name = t1.name
WHERE t2.name is null
To achieve your full requirements, you may find it more useful to have multiple queries accomplish the one task.
I was writing a mysql filter query which has a primary table and another table which holds multiple records against each record of primary table (I will call this table child).
Am trying to write a query which fetches record of primary table based on its values on child table. If the child table condition is one then I will be able to do it simply by joining, but I have 2 conditions which falls on same field.
For ex.
table 1:
id name url
1 XXX http://www.yahoo.com
2 YYY http://www.google.com
3 ZZZ http://www.bing.com
table 2:
id masterid optionvalue
1 1 2
2 1 7
3 2 7
4 2 2
5 3 2
6 3 6
My query has to return unique master records when the optionvalue matches only both 2 different conditions match on second table.
I wrote query with IN...
select * from table1
left join table2 on table1.id=table2.masterid
where table2.optionvalue IN(2,7) group by table1.id;
This gets me all 3 records because IN is basically checking 'OR', but in my case I should not get 3rd master record because it has values 2,6 (there is no 7). If I write query with 'AND' then am not getting any records...
select * from table1
left join table2 on table1.id=table2.masterid
where table2.optionvalue = 2 and table2.optionvalue = 7;
This will not return records as the and will fail as am checking different values on same column. I wanted to write a query which fetches master records which has child records with field optionvalues holds both 2 and 7 on different records.
Any help would be much appreciated.
Indeed, as AsConfused hinted, you need to two joins to TABLE2 using aliases
-- both of these are tested:
-- find t1 where it has 2 and 7 in t2
select t1.*
from table1 t1
join table2 ov2 on t1.id=ov2.masterid and ov2.optionValue=2
join table2 ov7 on t1.id=ov7.masterid and ov7.optionValue=7
-- find t1 where it has 2 and 7 in t2, and no others in t2
select t1.*, ovx.id
from table1 t1
join table2 ov2 on t1.id=ov2.masterid and ov2.optionValue=2
join table2 ov7 on t1.id=ov7.masterid and ov7.optionValue=7
LEFT OUTER JOIN table2 ovx on t1.id=ovx.masterid and ovx.optionValue not in (2,7)
WHERE ovx.id is null
You can try something like this (no performance guarantees, and assumes you only want exact matches):
select table1.* from table1 join
(select masterid, group_concat(optionvalue order by optionvalue) as opt from table2
group by masterid) table2_group on table1.id=table2_group.masterid
where table2_group.opt='2,7';
http://sqlfiddle.com/#!9/673094/9
select * from t1 where id in
(select masterid from t2 where
(t2.masterid in (select masterid from t2 where optionvalue=2))
and (t2.masterid in (select masterid from t2 where optionvalue=7)))
Old school :-) Query took 0.0009 sec.
This can also be done without the joins using correlated exists subqueries. That may be more efficient.
select *
from table1
WHERE EXISTS (SELECT 1 FROM table2 WHERE table1.id=table2.masterid and optionvalue = 2)
AND EXISTS (SELECT 1 FROM table2 WHERE table1.id=table2.masterid and optionvalue = 7)
If this is to be an exclusive match as suggested by, "when the optionvalue matches only both 2 different conditions match on second table" then you could ad yet a third exists condition. Performance-wise this may start to break down.
AND NOT EXISTS (SELECT 1 FROM table2 WHERE table1.id=table2.masterid AND optionvalue NOT IN (2,7)
Edit: A note on correlated subqueries from Which one is faster: correlated subqueries or join?.
I have 2 tables. I want to find out whether the values present in the first table is there in another table with a different field name.
Here is how it looks,
Table1
BillNo
43529179
43256787
35425676
25467778
24354758
45754748
Table2
BNo
113104808
25426577
268579679
2542135464
252525232
235263663
I have 137 records in table1 that needs to be checked against table2.
Instead of doing it one by one using the following command,
Select * from Table2 where BNo = '43529179';
This gives the result for just the mentioned value. Is there a way to check for all the values in a single query?
Thanks!
You can use a sub-select to compare against:
Select * from Table2 where BNo IN (SELECT BillNo FROM Table1);
That will "evalaute" to something like Select * from Table2 where BNo IN (113104808, 25426577, 268579679, 2542135464, 252525232, ...);
Join the tables, and check how many matching records there are:
select
count(*) as Matches
from
Table1 as t1
inner join Table2 as t2 on t2.BNo = t1.BillNo
You can also use a left join to pick out the records in table 1 that has no matching record in table 2:
select
t1.BillNo
from
Table1 as t1
left join Table2 as t2 on t2.BNo = t1.BillNo
where
t2.BNo is null
I don't know why I am confused with this query.
I have two table: Table A with 900 records and Table B with 800 records. Both table need to contain the same data but there is some mismatch.
I need to write a mysql query to insert missing 100 records from Table A to Table B.
In the end, both Table A and Table B should be identical.
I do not want to truncate all the entries first and then do a insert from another table. So please any help is appreciated.
Thank you.
It is also possible to use LEFT OUTER JOIN for that. This will avoid subquery overhead (when system might execute subquery one time for each record of outer query) like in John Woo's answer, and will avoid doing unnecessary work overwriting already existing 800 records like in user2340435's one:
INSERT INTO b
SELECT a.* FROM a
LEFT OUTER JOIN b ON b.id = a.id
WHERE b.id IS NULL;
This will first select all rows from A and B tables including all columns from both tables, but for rows which exist in A and don't exist in B all columns for B table will be NULL.
Then it filter only such latter rows (WHERE b.id IS NULL),
and at last it inserts all these rows into B table.
I think you can use IN for this. (this is a simpliplification of your query)
INSERT INTO table2 (id, name)
SELECT id, name
FROM table1
WHERE (id,name) NOT IN
(SELECT id, name
FROM table2);
SQLFiddle Demo
AS you can see on the demonstration, table2 has only 1 records but after executing the query, 2 records were inserted on table2.
If it's mysql and the tables are identical, then this should work:
REPLACE INTO table1 SELECT * FROM table2;
This will insert the missing records into Table1
INSERT INTO Table2
(Col1, Col2....)
(
SELECT Col1, Col2,... FROM Table1
EXCEPT
SELECT Col1, Col2,... FROM Table2
)
You can then run an update query to match the records that differ.
UPDATE Table2
SET
Col1= T1.Col1,
Col2= T1.Col2,
FROM
Table T1
INNER JOIN
Table2 T2
ON
T1.Col1 = T2.Col1
Code also works when a group by and having clauses are used. Tested SQL 2012 (11.0.5058) Tab1 is source with new records, Tab 2 is the destination to be updated. Tab 2 also has an Identity column. (Yes folks, real world is not as neat and clean as the lab assignments)
INSERT INTO Tab2
SELECT a.T1,a.T2,a.T3,a.T4,a.Val1,a.Val2,a.Val3,a.Val4,-9,-9,-9,-9,MIN(hits) MinHit,MAX(hits) MaxHit,SUM(count) SumCnt, count(distinct(week)) WkCnt
FROM Tab1 a
LEFT OUTER JOIN Tab2 b ON b.t1 = a.t1 and b.t2 = a.t2 and b.t3 = a.t3 and b.t4 = a.t4 and b.val1 = a.val1 and b.val2 = a.val2 and b.val3 = a.val3 and b.val4 = a.val4
WHERE b.t1 IS NULL or b.Val1 is NULL
group by a.T1,a.T2,a.T3,a.T4,a.Val1,a.Val2,a.Val3,a.Val4 having MAX(returns)<4 and COUNT(distinct(week))>2 ;