How to compare and insert different tables in sql? - sql

I have two different databases, the same column.I want to copy from the old database to the new database by comparing the student ID numbers between the tables and having the same number.
For example:
Database name 1: StudentInformation, table name: Student
StudentID Image
---------------------
123 1.png
142 2.png
175 3.png
475 4.png
Database name 2: StudentInformation2, table name: NewStudent
StudentID Image
--------------------------
145 a14.png
196 7.png
175 Null
875 9.png
475 Null
The two tables have common IDs (ID=175 and ID=475)
I want to get this table as a result:
New StudentInformation3, table name: NewSameStudents
StudentID Image
----------------------
175 3.png
475 4.png

You should try using the Merge Statement of SQL Server
Merge Statement Here

Here is one approach:
SELECT s1.StudentID, s1.Image
FROM StudentInformation.[schema].student s1
WHERE EXISTS (SELECT 1
FROM StudentInformation2.[schema].NewStudent s2
WHERE s1.StudentID = s2.StudentID
);
Demo
If you want to populate a new table using the results from the above select, then you may use the INSERT INTO ... SELECT construct:
INSERT INTO StudentInformation3.[schema].NewSameStudents (StudentID, Image)
SELECT s1.StudentID, s1.Image
FROM StudentInformation.[schema].student s1
WHERE EXISTS (SELECT 1
FROM StudentInformation2.[schema].NewStudent s2
WHERE s1.StudentID = s2.StudentID
);
But, I might recommend against this, since you can just create a (non materialized) view using the first query. Also, NewSameStudents is a derived table, and therefore might have to updated frequently, which could be a hassle.

Use inner join and isert into select statement for inserting in new table
insert into NewSameStudents(studentid,image)
select a.studentid,a.image from Student a inner join newstudent n
on a.studentid=n.studentid
where n.image is null

Below is the fully qualified SQL Query where it allows to select data between databases and even between different database servers.
SELECT * FROM [SERVER].[DATABASE].[SCHEMA].[TABLE]
SELECT
a.StudentID,
b.Image
FROM
StudentInformation.Student a
JOIN
StudentInformation2.Student b
ON a.StudentID = b.StudentID

Your 3rd table make no sense if you mean
New StudentInformation3, table name: NewSameStudents
StudentID Image
----------------------
175 3.png
475 4.png
You can use inner join
SELECT StudentID,Image
FROM StudentInformation1
INNER JOIN StudentInformation2
ON StudentInformation1.StudentID = StudentInformation1.StudentID;

try this:
WITH StudentInformation AS (
SELECT 123 AS StudentID, '1.png' AS Image UNION ALL
SELECT 142, '2.png' UNION ALL
SELECT 175, '3.png' UNION ALL
SELECT 475, '4.png'
),
StudentInformation2 AS (
SELECT 145 AS StudentID, 'a14.png' AS Image UNION ALL
SELECT 196, '7.png' UNION ALL
SELECT 175, NULL UNION ALL
SELECT 875, '9.png' UNION ALL
SELECT 475, NULL
)
SELECT s1.StudentID, s1.Image
FROM StudentInformation2 s2 left join
StudentInformation s1 ON s1.StudentID = S2.StudentID

Use Merge From SQL:
Merge into [TABLE_TARGET] as u
USING (Select * from TABLE) as c
on
u.FIELD1 = c.FIELD2 ---JOIN
--------------------
WHEN MATCHED THEN
-------------------
Update SET
FIELD_FROM_TARGET = c.FIELD_FROM_TABLE
----------------------
WHEN NOT MATCHED THEN
----------------------
Insert (
FIELD_FROM_TARGET
) VALUES
(
FIELD_FROM_TABLE
);

Related

Attempting to update table data from another table SQL #SQL

I have two tables, one called whoop_data with fields (id, user_id, date, recovery, sleep, strain)
and another called whoop_user with fields (id, name, average_recovery, average_sleep, average_strain)
I'd like to update the whoop_user average data fields using the whoop_data that is logged. Below are my attempts to do so.
New to SQL - please be kind :)
The code below results in the following table (works as intended):
name
AVG(recovery)
Name2
39.5
Name1
78
Name3
49.5
/*works as intended*/
SELECT name, AVG(recovery) FROM whoop_users JOIN whoop_data
ON whoop_users.id = whoop_data.user_id
GROUP BY name;
Both of the attempts below result in the following table:
Name
average_recovery
Name1
39.5
Name2
39.5
Name3
39.5
I see what is happening, but I don't understand why, how to fix it, or why the statement above DO work as intended and the ones below don't.
/*attempt 1*/
UPDATE whoop_users
SET
average_recovery = (SELECT AVG(recovery)
FROM whoop_users JOIN whoop_data ON
whoop_users.id = whoop_data.user_id
GROUP BY name)
WHERE
EXISTS (
SELECT * FROM whoop_data
WHERE whoop_data.user_id = whoop_users.id );
SELECT * FROM whoop_users;
/*attempt 2*/
WITH a AS
(
SELECT AVG(recovery) as av
FROM whoop_users JOIN whoop_data
ON whoop_users.id = whoop_data.user_id
GROUP BY name
)
UPDATE whoop_users
SET
average_recovery = (SELECT av FROM a);
SELECT * FROM whoop_users;
You must correlate properly the subquery that returns the averages from whoop_data (no joins are needed):
UPDATE whoop_users AS u
SET (average_recovery, average_sleep, average_strain) =
(
SELECT AVG(d.recovery), AVG(d.sleep) avg_sleep, AVG(d.strain)
FROM whoop_data AS d
WHERE d.user_id = u.id
);
If your version of SQLite is 3.33.0+ you could also use the UPDATE...FROM syntax which sometimes performs better:
UPDATE whoop_users AS u
SET average_recovery = d.avg_recovery,
average_sleep = d.avg_sleep,
average_strain = d.avg_strain
FROM (
SELECT user_id,
AVG(recovery) avg_recovery,
AVG(sleep) avg_sleep,
AVG(strain) avg_strain
FROM whoop_data
GROUP BY user_id
) AS d
WHERE u.id = d.user_id;

output of one query as a table to select the values from in next query

I have a Question output of my query as a table to select the values from in my next query please suggest your views.
example with DB tables I am using:
First Query:
WITH TABLE1
AS (SELECT COT.DESCRIPTION
FROM CONFIGURABLEOBJECTTYPE COT
WHERE COT.CONFIGURABLEOBJECTTYPEID IN (SELECT CIO.DAMAGEDCOTEMPLATE
FROM CLAIMINSURANCEOBJECT CIO
INNER JOIN CLAIMRISKUNIT CRU ON CRU.CLAIMRISKUNITID = CIO.CLAIMRISKUNITID
INNER JOIN CLAIM CL ON CL.CLAIMID = CRU.CLAIMID
INNER JOIN AGREGATEDPOLICY APO ON CL.POLICYID = APO.AGREGATEDPOLICYID))
OUTPUT:
RecSuiVidaCol,
RecSuiSegMigranteVida,
RecEnfSegMigranteVida,
RecAccPasajeroSeguro,
RecAgrSaldosDeudores,
RecEnfPasajeroSeguro,
RecAccSegMigranteVida,
RecAccVidaCol,
(All of the above are DB Tables again)
Now My second Query:
SELECT * FROM TABLE1 WHERE PK IN (SELECT CIO.DAMAGEDCOID
FROM CLAIMINSURANCEOBJECT CIO
INNER JOIN CLAIMRISKUNIT CRU ON CRU.CLAIMRISKUNITID = CIO.CLAIMRISKUNITID
INNER JOIN CLAIM CL ON CL.CLAIMID = CRU.CLAIMID
INNER JOIN AGREGATEDPOLICY APO ON CL.POLICYID = APO.AGREGATEDPOLICYID);
Field PK is not identified here.
I want all the fields as output from the table based on the condition
A CTE ( with clause ), perhaps?
WITH XYZ
AS (
SELECT 'Ayub' as Name
FROM Dual
)
SELECT *
FROM XYZ;
The following is for SQL*Plus. It may work in SQL Developer, as that tends to do a good job of emulating SQL*Plus:
SQL> column testname new_value testname
SQL> select 'user_sequences' as testname from dual;
old 1: select count(*) from &testname
new 1: select count(*) from user_sequences
TESTNAME
--------------
user_sequences
1 row selected.
SQL> select count(*) from &testname;
COUNT(*)
----------
4
1 row selected.
SQL> define testname
DEFINE TESTNAME = "user_sequences" (CHAR)
Notes:
The old and new values are displayed because I set verify on.
The new_value option is part of the column command.

Combine two table for one output sql query

I have two tables
Threads:
i_id thread_note seq_id
1 ABC 2
2 CDE 2
3 FGH 1
4 IJK 2
Notes:
i_id note_text entered_date
1 stack 09/08/2017
5 queue 07/07/2014
3 push 09/07/1996
I want the output as
i_id thread_note seq_id note_text entered_date
1 ABC 2 stack 09/08/2017
2 CDE 2 null null
3 FGH 1 push 09/07/1996
4 IJK 2 null null
5 null null queue 07/07/2014
How do I achieve this? The tables are not related to each other.
Note: This is different from most of the questions similar to this asked because there are some "i_id" values which are present in threads table but not in notes table and there are some "i_id" values present in notes table but not in threads table
Use a full outer join:
SELECT
COALESCE(t.i_id, n.i_id) AS i_id,
t.thread_note,
t.seq_id,
n.note_text,
n.entered_date
FROM Threads t
FULL OUTER JOIN Notes n
ON n.i_id = t.i_id
ORDER BY
i_id;
Note that having the need to do a full outer join often can indicate a problem with your relational model, because it means you don't know the key relationships between your tables.
Demo
Edit:
If you are using a database such as MySQL which does not support a full outer join, we can still simulate one:
SELECT *
FROM Threads t
LEFT JOIN Notes n
ON n.i_id = t.i_id
UNION ALL
SELECT *
FROM Threads t
RIGHT JOIN Notes n
ON n.i_id = t.i_id
WHERE t.i_id IS NULL;
First, you need to get all i_id from all tables in a subquery. Once you have the rows, join this to the two tables to get the columns you need,
SELECT a.i_id,
b.thread_note,
b.seq_id,
c.Note_text,
c.entered_date
FROM
(
SELECT i_id FROM Threads UNION
SELECT i_id FROM Notes
) a
LEFT JOIN Threads b
ON a.i_id = b.i_id
LEFT JOIN Notes c
ON a.i_id = c.i_id
ORDER BY a.i_id
Here's a Demo.
You could just use a FULL OUTER JOIN here. If I make some test data:
DECLARE #threads TABLE (i_id INT, thread_note NVARCHAR(3), seq_id INT);
INSERT INTO #threads SELECT 1, 'ABC', 2;
INSERT INTO #threads SELECT 2, 'CDE', 2;
INSERT INTO #threads SELECT 3, 'FGH', 1;
INSERT INTO #threads SELECT 4, 'IJK', 2;
DECLARE #notes TABLE (i_id INT, note_text NVARCHAR(10), entered_date DATE);
INSERT INTO #notes SELECT 1, 'stack', '20170809';
INSERT INTO #notes SELECT 5, 'queue', '20140707';
INSERT INTO #notes SELECT 3, 'push', '19960709';
Then my query is simply:
SELECT
ISNULL(t.i_id, n.i_id) AS i_id,
t.thread_note,
t.seq_id,
n.note_text,
n.entered_date
FROM
#threads t
FULL OUTER JOIN #notes n ON n.i_id = t.i_id
ORDER BY
ISNULL(t.i_id, n.i_id);
No need to make a list of unique I_ids.
Use the below query
select Isnull(n.i_id,t.i_id), [thread_note],seq_id,Notetest,Enddate
from [dbo].[note] n FULL OUTER JOIN [dbo].[thread] t on n.[i_id]=t.[i_id]
order by Isnull(n.i_id,t.i_id)

right join not giving values null

I have two tables as:
select * from CallTypeDescription
select * from CallTypeDetails
I want to show all the records of idcalltype against its idjob.
Eg.
If idJob in CallTypeDescription is 96 and idCallType is 4 it should show records:
if idJob is 94 (i.e. does not exists in callType description) and idCallType is 4 then result should be:
Title Value idJob
test qu1 Null Null
test qu2 Null Null
For this i tried:
select a.Title,b.Value,b.idJob from CallTypeDescription b
right join CallTypeDetails a
on a.idCallType=b.idCallType
and a.idDetails=b.idCallTypeDetail
where a.idCallType=4 and b.idJob=96
But gives me result:
It should also add another row with test qu2 null null.
Plese help me.
Edit:
select a.Title,b.Value,b.idJob from CallTypeDescription b
right join CallTypeDetails a
on a.idCallType=b.idCallType
and a.idDetails=b.idCallTypeDetail
and a.idCallType=4
where b.idJob=96
It looks like you are after this effect (SQL Fiddle: http://sqlfiddle.com/#!3/8f98e/10):
select
a.Title,b.Value,b.idJob
from
(
select
IdDesc,
IdCallType,
IdJob,
IdCallTypeDetail,
Value
from
CallTypeDescription
where
IdJob = 96 --or 94
) b
right outer join
CallTypeDetails a
on
a.idCallType=b.idCallType
and
a.idDetails=b.idCallTypeDetail
where
a.idCallType=4
Is there a reason you have chosen to use a right join instead of a left one?
Remove the line that constrains the query to only return rows where the idDetails and isCallTypeDetail are equal:
select a.Title,b.Value,b.idJob
from CallTypeDescription b inner join CallTypeDetails a
on a.idCallType=b.idCallType
where a.idCallType=4 and b.idJob=96

Tricky SQLite query, could use some assistance

I have a rather confusing SQLite query that I can't seem to quite wrap my brain around.
I have the following four tables:
Table "S"
sID (string/guid) | sNum (integer)
-----------------------------------
aaa-aaa 1
bbb-bbb 2
ccc-ccc 3
ddd-ddd 4
eee-eee 5
fff-fff 6
ggg-ggg 7
Table "T"
tID (string/guid) | ... other stuff
-----------------------------------
000
www
xxx
yyy
zzz
Table "S2TMap"
sID | tID
-------------------
aaa-aaa 000
bbb-bbb 000
ccc-ccc xxx
ddd-ddd yyy
eee-eee www
fff-fff 000
ggg-ggg 000
Table "temp"
oldID (string/guid) | newID (string/guid)
------------------------------------------
dont care fff-fff
dont care ggg-ggg
dont care zzz
What I need is to be able to get the MAX() sNum that exists in a specified "t" if the sID doesn't exist in the temp.NewID table.
For example, given the T '000', '000' has S 'aaa-aaa', 'bbb-bbb', 'fff-fff', and 'ggg-ggg' mapped to it. However, both 'fff-fff' and 'ggg-ggg' exist in the TEMP table, which means I need to only look at 'aaa-aaa' and 'bbb-bbb'. Thus, the statement would return "2".
How would I go about doing this?
I was thinking something along the lines of the following for selecting s that don't exist in the "temp" table, but I'm not sure how to get the max of the seat and only do it based on a specific 't'
SELECT s.sID, s.sNum FROM s WHERE NOT EXISTS ( SELECT newID from temp where tmp.newID = s.sID)
Thanks!
Give this a try:
select max(s.sNum) result from s2tmap st
join s on st.sId = s.sId
where st.tId = '000' and not exists (
select * from temp
where temp.newId = st.sId)
Here is the fiddle to play with.
Another option, probably less efficient would be:
select max(s.sNum) result from s2tmap st
join s on st.sId = s.sId
where st.tId = '000' and st.sId not in (
select newId from temp)
The following query should give you a list of Ts and their max sNums (as long as all exist in S and S2TMap):
SELECT t.tID, MAX(sNum)
FROM S s
JOIN S2TMap map on s.sID=map.sID
JOIN T t on map.tId=t.tID
LEFT JOIN temp tmp on s.sID=tmp.newID
WHERE tmp.newID IS NULL
You were close, you just had to join on S2TMap and then to T in order to restrict the result set to a given T.
SELECT MAX(s.sNum)
FROM s
INNER JOIN S2TMap m on m.sID = s.sID
INNER JOIN t on t.tID = m.tID
WHERE t.tID = '000'
AND NOT EXISTS (
SELECT newID FROM temp WHERE temp.newID = s.sID
)