Update column with value from another table using SQLite? - sql

I have two SQLite tables. I want to update a column in table1 with a value from table2.
Table 1, table1 (id INTEGER AUTOINCREMENT, status TEXT, name TEXT);:
| id | status | name |
|----|-----------|------|
| 1 | pending | xyz |
| 2 | completed | abc |
Table 2, table2 (status TEXT, name TEXT, trans_id INTEGER);:
| trans_id | status | name |
|----------|-----------|------|
| 1 | refunded | cvb |
| 2 | cancelled | asd |
I want to update status and name from table2 to table1 where table1.id = table2.trans_id. I have this query:
UPDATE table1
SET status = (SELECT t2.status FROM table1 t1,table2 t2 WHERE t1.id = t2.trans_id) ,
name = (SELECT t2.name FROM table1 t1,table2 t2 WHERE t1.id = t2.trans_id)
WHERE id IN (SELECT trans_id FROM table1 t1,table2 t2 WHERE t1.id = t2.trans_id)
It populates table1 wrongly. This is the resultant table1
| id | status | name |
|----|----------|------|
| 1 | refunded | cvb |
| 2 | refunded | cvb |
My requirement is this:
| id | status | name |
|----|-----------|------|
| 1 | refunded | cvb |
| 2 | cancelled | asd |
Whats wrong with my query? How can I achieve it?

I am assuming that the t2.trans_id is uniq or primary key in table2. If not then if it return multiple result then the update query will blow up. In that case either you need to apply the more filter using the WHERE or use the TOP 1 if any result will be needed.
UPDATE table1
SET status = (SELECT t2.status FROM table2 t2 WHERE t2.trans_id = id) ,
name = (SELECT t2.name FROM table2 t2 WHERE t2.trans_id = id)
WHERE id IN (SELECT trans_id FROM table2 t2 WHERE t2.trans_id= id)

The previous answer will be failed if there is the id column in the table2. It would be better that using the full name table1.id
UPDATE table1
SET status = (SELECT t2.status FROM table2 t2 WHERE t2.trans_id = table1.id) ,
name = (SELECT t2.name FROM table2 t2 WHERE t2.trans_id = table1.id)
WHERE id IN (SELECT trans_id FROM table2 t2 WHERE t2.trans_id= table1.id);

Related

How to find rows that have only one value in another table

I want to find rows from table 1 that are joining with table 2 and have all rows same in table 2.
Example:
Row with id 4 in table2 is not valid because have different values in table1 (value1, value)
Row with id 5 in table2 is valid because have same values in table1 (value3)
table1
+----+--------+----------+
| id |table2Id| value |
+----+--------+----------+
| 1 | 4 |value1 |
| 2 | 4 |value2 |
| 3 | 5 |value3 |
| 4 | 5 |value3 |
| 5 | 5 |value3 |
+----+--------+----------+
table2
+----+
| id |
+----+
| 4 |
| 5 |
+----+
I'm not sure why a join is necessary. You can just use the information in table1:
select t1.*
from (select t1.*,
min(value) over (partition by table2id) as min_value,
max(value) over (partition by table2id) as max_value
from table1 t1
) t1
where min_value = max_value;
Or use not exists:
select t1.*
from table1 t1
where not exists (select 1
from table1 tt1
where tt1.table2id = t1.table2id and
tt1.value = t1.value
);
In either case, you can join to table2 if you need to for filtering or for other columns, but based on the information in your question the join is not needed.
You can do the following:
SELECT * FROM (
SELECT max(table2Id) as Id,value
FROM table1
GROUP BY value
HAVING COUNT(value)=1) JOIN table2 on table1.Id = table2.Id
Thanks
Try this -
Select t1.* from table1 t1 JOIN table2 t2 on t1.id = t2.id and t1.table2Id = t2.id

Oracle SQL Query with joining four tables to get only one row of multiple entries

My tables are set up something like this:
Table 1 Table 2 Table 3
+-------+-----+ +-------+-------+-------+-----+ +-------+-----+
| ID | ... | | ID | T1_ID | T3_ID | ... | | ID | ... |
+-------+-----+ +-------+-------|-------|-----| |-------|-----|
| 101 | ... | | 202 | 101 | 301 | ... | | 300 | ... |
| 102 | ... | | 203 | 101 | 302 | ... | | 302 | ... |
| 104 | ... | | 204 | 101 | 302 | ... | | 314 | ... |
+-------+-----+ | 205 | 101 | 302 | ... | +-------+-----+
| 206 | 104 | 327 | ... |
+-------+-------+-------+-----+
I want to construct a subquery statement that will select only one row of table 2 for an given id of table 1, if table2.t3_id exists in table 3.
The important point is that there maybe exist multiple rows with same t3_id in table 2. So, the foreign key relation between table 2 and table 3 is not unique or does not exist at all.
My idea was the following statement:
inner join
(
SELECT *
FROM (
SELECT t3_id, t1_id, id
FROM table2
WHERE EXISTS
(
SELECT id
FROM table3
)
)
WHERE ROWNUM=1
) tb2 ON tb1.id = tb2.t1_id
This statement returns multiple rows, but I only need one.
How do I do this?
Not tested but should do what you need
SELECT *
FROM table1 t1 JOIN table2 t2
ON ( t1.id = t2.t1_id
AND EXISTS ( SELECT 'x'
FROM table3 t3
WHERE t2.t3_id = t3.id
)
AND NOT EXISTS ( SELECT 'a'
FROM table2 t22
WHERE t22.t1_id = t2.t1_id
AND t22.id < t2.id
)
)
You can get one row of multiple entries by using row_number() to enumerate them and then selecting just one value. Here is an example:
select . . .
from table1 t1 join
(select t2.*, row_number() over (partition by t.id order by t2.id) as seqnum
from table2 t2
) t2
on t2.t1_id = t1.id and t2.seqnum = 1;
EDIT:
For all three tables, you want to do the row_number() all the joins:
select . . .
from (select . . ., row_number() over (partition by t1_id order by id) as seqnum
from table1 t1 join
table2 t2
on t2.t1_id = t1.id join
table3 t3
on t2.t3_id = t3.id
) t
where seqnum = 1;

Merge from 1 table to another

I have the following two tables:
table 1 table 2
+-------------+------+ +-------------+------+
| ssn | id | | ssn | id |
+-------------+------+ +-------------+------+
| 123456789 | 123 | | 123456789 | k12 |
| 123456789 | 456 | | 999999999 | k11 |
| 123456789 | 789 | +-------------+------+
| 123456789 | k12 |
| 999999999 | 799 |
+-------------+------+
What I want to do is to merge the data in table 2 with the data in table 1 if there is no matching id. So 123456789 should be ignored as the member already shows with the id k12. Record 999999999 k11 should be added to table 1.
A few ways to do this. Here's one using NOT EXISTS:
INSERT INTO Table1
SELECT T2.ssn, T2.id
FROM Table2 T2
WHERE NOT EXISTS (
SELECT 1
FROM Table1 T1
WHERE T1.id = T2.id)
Or you could use NOT IN:
INSERT INTO Table1
SELECT ssn, id
FROM Table2
WHERE id NOT IN (SELECT id FROM Table1)
INSERT INTO #Table1
( ssn, id)
SELECT t2.ssn, t2.id
FROM #table2 as t2
LEFT JOIN #table1 as t1
ON t1.id = t2.id or t1.ssn = t2.ssn
WHERE t1.id IS NULL;
if you are worried about duplicates in either id OR ssn, this will only insert when both are unique
If this is something you need to do often on large tables, this LEFT JOIN approach may perform a bit faster.
INSERT INTO Table1
SELECT T2.ssn, T2.id
FROM Table2 T2
LEFT JOIN Table1 t1 ON t1.id = t2.id
WHERE t1.id IS NULL

update data in table based on data in another table

table1
-----------------------------
| id (int) | dt (datetime) |
-----------------------------
| 1 | 12-12-2012 |
| 2 | 13-11-2013 |
| 3 | 23-07-2014 |
| 4 | 13-06-2014 |
-----------------------------
table2
-----------------------------
| id (int) | dt2 (datetime) |
-----------------------------
| 1 | 12-12-2012 |
| 1 | 13-11-2013 | -> update table1 id=1 with this dt2
| 2 | 23-07-2014 |
| 2 | 13-06-2014 |
| 2 | 12-12-2012 | -> update table1 id=2 with this dt2
| 3 | 13-11-2013 | -> update table1 id=3 with this dt2
| 3 | 23-07-2014 |
| 3 | 13-06-2014 |
| 4 | 23-07-2014 |
| 4 | 13-02-2014 | -> update table1 id=4 with this dt2
-----------------------------
I want to update table1.dt with the corresponding dt2 from table2 based on the id.
However, I do not want to update table1.dt to the largest corresponding datetime value from table2.dt2.
I only want to update dt to the largest corresponding dt2 which is not greater than the current date.
So far what I have gotten is:
update table1
set table1.dt = table2.dt2
from table2
inner join table1 on table1.id = table2.id
where ?table1.id=table2.id and...?
No idea how to modify the sql statement such that it will only update dt to the largest corresponding dt2 which is not greater than the current date.
Hope it isn't too confusing...
Try this
UPDATE table1
SET [dbo].[Table1].dt = [dbo].[Table2].dt2
FROM [dbo].[Table2]
where [dbo].[Table2].id = [dbo].[Table1].id and [dbo].[Table2].dt2 > [dbo].[Table1].dt
and [dbo].[Table2].dt2 <= getdate()
If i'm correcting in what you're trying to achieve you are after the "where" statement that says: where id's are equal and date in Table2 is greater that what you already have in table1 and the date in table2 is less than today? then update.
You could either using group and aggregates by in your derived table there, or possibly look into cross apply. Here's an example of the former.
update table1
set table1.dt = table2.dt2
from table1 join (
select id,max(dt2) as maxDT
from table2
group by id) as derivedTable2 on derivedTable2 .id = table1.id
Something like this construct would work:
UPDATE table1
SET dt = dt2
FROM ( SELECT id AS _id ,
MAX(dt2) AS dt2
FROM ( SELECT T2.id ,
T2.dt2
FROM Table1 T1
INNER JOIN Table2 T2 ON T1.id = T2.id
WHERE T2.dt2 < T1.dt
) A
GROUP BY id
) B
WHERE id = _id;

MySQL get data from another table with duplicate ID/data

How to query data from table_1 which ID is not available on table_2 that has duplicate ID's. See example below.
I want to get ID 5 and 6 of Table 1 from Table 2
Table 1
-------------
| ID | Name |
| 1 | a |
| 2 | b |
| 3 | c |
| 4 | d |
| 5 | e |
| 6 | f |
-------------
Table 2
-------------
Table 1 ID |
| 1 |
| 1 |
| 2 |
| 2 |
| 2 |
| 3 |
| 4 |
-------------
Thanks!
Minus query would be very helpful, see this link: minus query replacement
for your data this would look like this:
SELECT table_1.id FROM table_1 LEFT JOIN table_2 ON table_2.id = table_1.id WHERE table_2.id IS NULL
Use:
SELECT t.id
FROM TABLE_1 t1
LEFT JOIN TABLE_2 t2 ON t2.id = t1.id
WHERE t2.id IS NULL
Using NOT EXISTS:
SELECT t.id
FROM TABLE_1 t1
WHERE NOT EXISTS(SELECT NULL
FROM TABLE_2 t2
WHERE t2.id = t1.id)
Using NOT IN:
SELECT t.id
FROM TABLE_1 t1
WHERE t1.id NOT IN (SELECT t2.id
FROM TABLE_2 t2)
Because there shouldn't be NULL values in table2's id column, the LEFT JOIN/IS NULL is the fastest means: http://explainextended.com/2009/09/18/not-in-vs-not-exists-vs-left-join-is-null-mysql/
If I am understanding you correctly you want to do an outer join. In this case it would be:
SELECT * FROM
table_1 LEFT JOIN ON table_2
ON table_1.id = table_2.id
WHERE table_2.id is NULL
This one does what you want:
Select t1.id
From table1 t1
Left Join table2 t2
On t2.id = t1.id
Where t2.id Is Null
Result:
id
--
5
6