Deleting duplicates from composite Primary key in SQL server - sql

I am using SQL server 2012.
I have two tables with identical structure. (Say there are four columns - ID, C2, C3, C4)
I want to copy data from Table1 to Table2.
The only difference between the two tables is that Table1 contains the local ID in the 'ID' field and table 2 should have the global ID.
There is another third table that contains this mapping between the localID and the global ID.
(multiple local ID's can be mapped to one Global ID)
Example:
ID 'abcd' in russia can be global ID 123
ID 'cdef' in china can be global ID 123
therefore abcd in russia is basically cdef in china (this mapping is stored in table3)
I want to take the GlobalID from table3 corresponding to the local ID that we have in Table1 and insert them into table2.
Table2 has a primary key constraint defined on the column ID+C2.
The problem is that there are high chance we'll have duplicate data - So we want to insert only distinct combination of ID+C2. (clustered PK)
Can someone please help me with this? Sorry if this is confusing.
I right now have this query, but it doesnt eliminates duplicates when copying data from T1 to T2 and thus I get an error on PK.
INSERT INTO TABLE2
(ID,
C2,
C3,
C4)
SELECT T3.ID,
T1.C2,
T1.C3,
T1.C4
FROM TABLE1 T1
JOIN TABLE3 T3 ON T1.ID = T3.ID
JOIN TABLE2 T2 ON T2.ID = T1.ID

I'm not sure, but I guess you want something like
INSERT INTO Table2 (globalID)
SELECT DISTINCT m.globalID from Mapping m inner join Table1 t
on t.country = m.country and t.localId = m.localID
You can use any select, so alter it for your needs.

Related

How can I effectively check uniqueness of an item in database?

I have a spreadsheet that needs to be uploaded. But each row needs to be check if they are unique in the database. One option that I can think of is to check each row exists in the database or not, that means doing N sql queries for N rows. Is there any alternatives on effectively checking for unique data instead of checking row by row?
we can do that by using NOT EXISTS and NOT IN methods. To do that, first we need to insert that spreadsheet data's into one temp table.
lets take your main table as TABLE_1 and your spreadsheet temp table as TABLE_2.
Using NOT IN -
INSERT INTO TABLE_1 (id, name)
SELECT t2.id, t2.name FROM TABLE_2 t2
WHERE t2.id NOT IN (SELECT id FROM TABLE_1)
Using NOT EXISTS -
INSERT INTO TABLE_1 (id, name)
SELECT t2.id, t2.name FROM TABLE_2 t2
WHERE NOT EXISTS(SELECT id FROM TABLE_1 t1 WHERE t1.id = t2.id)

How to make sql query using two tables

I have 3 tables T1,T2 and T3. Table T1 contains 2 columns (key,class/student). The column class/student contains both classes and students, for example: 'english', 'math', 'mark', 'tom'... Table T2 contains 2 columns (class,student). Each class have more than one student in it, and these 2 columns use the keys from T1. In Table T3 I want to insert a specific class with its student(s) - class(es) into column A and student(s) into column B. Knowing that these columns use the keys from T1 table I've tried this but it returns same specific class with its students multiple times:
INSERT INTO T3 (A,B)
SELECT m.class, m.student
FROM T1 b,T2 m
WHERE m.class = (SELECT key FROM T1 WHERE class/student='English')
AND b.KEY = m.student;
the result i get: 1 is id of class english ,10 is id of student mark, 11 is id of student tom
table T1:
Table T2:
Since your master table T1 has both class and student details, I would recommend joining it twice with the class_student_map table T2 to get the details:
INSERT INTO T3 (A,B)
SELECT "class_master"."key", "student_master"."key"
FROM
T2 "class_student_map"
INNER JOIN
T1 "class_master"
ON
"class_master"."key" = "class_student_map"."class"
AND
"class_master"."class/student" = 'English'
INNER JOIN
T1 "student_master"
"student_master"."key" = "class_student_map"."student";
Here you have simple code and just one join operation, which positively impacts on performance:
insert into t3
WITH spec_class AS
(select key from T1 where class_student='English')
SELECT m.class, m.student
FROM T2 m inner join spec_class sp on m.class=sp.key;

SQL join to return a table with multiple columns from other tables replacing its own

I am trying to write an SQL query that will return Table1, which has 10 columns. This table consists of a primary key id, 4 foreign key Id columns, and 5 other columns that I want to return but not change. The goal is to do a join to replace the foreign key Ids with their descriptions that are held in other tables.
Here is one attempt with the first FK Id:
Select * from Table1 t1
left join Table2 t2
on t1.BranchId = t2.BranchId;
This left join returns the description from table2, but does not replace it.
Here is another with the first FK Id:
Select t2.BranchName from Table1 t1
left join Table2 t2
on t1.BranchId = t2.BranchId;
This returns the name I want, but does not return table1 fully.
For the sake of an example you could pretend that OtherName3, OtherName4, OtherName5 are in tables Table3, Table4, Table5, respectively.
This may seem trivial for experienced SQL devs, but I am having a hard time figuring out the syntax.
Thanks!
I'm not sure what you mean by replace it.
I think you just need to list out all the columns you want:
Select t1.col1, t1.col2, t1.col3, . . .,
t2.name
from Table1 t1 left join
Table2 t2
on t1.BranchId = t2.BranchId;
I don't know what you mean by 'replace' but you just need to qualify what columns from which table you want. That goes for all tables you are joined to, especially if they have the same column name in multiple tables. I put junk columns in since I don't know your tables but you should get the general idea.
Select t2.BranchName, t1.BranchId, t1.Name, t1.Amount, t2.BranchLocation from Table1 t1
left join Table2 t2
on t1.BranchId = t2.BranchId;
I think this is what you are looking for:
select t1.*, t2.BranchName from Table1 t1
left join Table2 t2
on t1.BranchId = t2.BranchId;
Return Table1 fully (all columns) and only the description (BranchName) from Table2.
If using SQL Server, see all syntax options for the SELECT clause here:
https://msdn.microsoft.com/en-us/library/ms176104.aspx

select a column in foreign key

Suppose I have two tables in SQL where
table1 has columns - id, name, sex.
table2 has columns - eid, group, hours.
column 'eid' is the foreign key in table2 and column 'id' is the primary key on table1.
suppose I conduct a search using 'select * from table2 where hour=x' in table 2 and get some results. How can I list the names of the people (from table1) associated with the ids from the search?
GOt it!
SELECT T1.NAME FROM TABLE2 T2
INNER JOIN TABLE1 T1 ON (T1.ID=T2.EID)
WHERE T2.HOUR=X

sql query distinct join

Sorry I missed and deleted earlier question on accident again.
I have a situation, I am trying to select distinct values from table 1 that are new and store them in table 2. The problem is that table has duplicates on column "name" but it does have a key column "id", but the different ids of course map to the same name.
My idea on the query would be
INSERT INTO TABLE2
(NAME, UniqueID)
SELECT DISTINCT TABLE1.NAME, TABLE1.ID
FROM TABLE1
LEFT JOIN TABLE2 ON TABLE1.ID=TABLE2.UniqueID
WHERE TABLE2.NAME IS NULL
Need help on getting the query to return my desired results, right now it still produces duplicates in table2 (on name column), which I don't want. I would want it to only append new records even if I run the query multiple times. For example if two new records were added into table1 but one has the name already in table 2, then the query would only add 1 new record to table2
just a note: I am using ms access, so it has strict syntax on single queries
EDIT:
Folliwing input I had came with this query
INSERT INTO TABLE2
(NAME, UniqueID)
SELECT TABLE1.NAME, Min(TABLE1.ID)
FROM TABLE1
LEFT JOIN TABLE2 ON TABLE1.NAME=TABLE2.NAME
WHERE TABLE2.UniqueID IS NULL
Group By TABLE1.NAME;
but these actually had to be separated to two separate wueries in access to run without a reserver error flag but now I ran into additional problem. When I run the two separate queries, it works fine the first time, but when I run it twice trying to test to see if any new records have been added to table 1, it then appends 1 record when no new records are in table 1, so it appends a blank name value and a duplicate unique id, and continually does that same process everytime I run it.
Since you're pulling both Name and ID, the distinct keyword will only pull distinct combinations of those. Two records with the same Name and different ID's is still valid.
In the case of two Names with different ID's, which would you like to be inserted?...
insert into table2 (Name, UniqueID)
select t1.Name, MIN(t1.ID)
from table1 t1
left join table2 t2 on t1.ID = t2.UniqueID
where t2.Name is null
group by t1.Name
in response to comments, I realize the Name field is what should be joined on, to prevent dupes that already exist.
insert into table2 (Name, UniqueID)
select t1.Name, MIN(t1.ID)
from table1 t1
left join table2 t2 on t1.Name = t2.Name
where t2.UniqueID is null
group by t1.Name
INSERT INTO TABLE2 (UniqueID, NAME)
SELECT min(t1.ID) as UniqueID, t1.NAME
FROM TABLE1 t1
LEFT JOIN TABLE2 t2 ON t1.ID=t2.UniqueID
WHERE t2.NAME IS NULL
group by t1.NAME