SQL - Linking two tables - sql

I have two tables, specifically, they contain standard and specific parameters respectively.
Table1:
PKParameter Name Unit
1 Temperature K
2 Length mm
3 Pressure bar
Table2:
PKSpecParam Name Unit
1 Weight kg
2 Area m2
PKParameter ans PKSpecParameter are primary keys
I would like to combine these two tables into a third table which will keep track of the primary keys so I can reference any of the parameters, regardless of the table they are from.
For example:
PKCombined PKParameter PKSpecParameter
1 1 NULL
2 2 NULL
3 3 NULL
4 NULL 1
5 NULL 2
Now I would like to use PKCombined primary key to reference parameter
Maybe there is a better way to do this, but I've just started meddling with databases.

Select a.PKParameter , a.name,a.unit,b.PKSpecParam , b.name,b.unit
from table1 a outer join table2 b on a.pkparameter=b.pkspecparam
However, this will give out null values if number of entries in pkparameter and pkspecparam dont match

Related

How to display data in SQL from multiple tables, but only if one column data matches another column?

I'm still learning SQL, so this may just be my ignorance or inability to express in a search what I'm looking for. I've spent roughly an hour searching for some variation of the title (both here and general searches on Google). I apologize, I apparently also don't know how to format here. I'll try to clean it up now that I've posted.
I have a database of customer data that I did not design. In the GUI, there are multiple tabs, and it seems like each tab earned it's own table. The tables are linked together with a field called RecordID. In one of the tables is the Customer Data tab. The way that it's organized is that a single customer record from table A can have multiple rows in table B. I only want data from column B in table B is "CompanyA" and if column A in table B = 1. Sample data is below.
Expected output:
CardNumber LastName FirstName CustomerID DataItem
------------------------------------------------------
32154 Clapton Eric 181212 CompanyA
Table A:
RecordID CardNumber LastName FirstName CustomerID
---------------------------------------------------------------
1 12345 Smith John 190201
2 12346 Jones Sandy 190202
3 23456 Petty Tom 190203
4 32154 Clapton Eric 181212
5 14728 Tyler Steven 180225
Table B:
RecordID DataID DataItem
--------------------------------
1 0 CompanyA
1 1 Yes
1 2 No
1 3 Revoked
1 4 NULL
1 5 CompanyB
2 0 CompanyB
2 1 Yes
2 2 No
2 3 NULL
2 4 24-54A
2 5 CompanyC
3 0 CompanyA
3 1 No
3 2 No
3 3 NULL
3 4 68-69B
3 5 NULL
4 0 CompanyA
4 1 Yes
4 2 Yes
5 0 CompanyB
5 1 No
5 2 No
5 5 CompanyA
The concept you're looking for is a JOIN. In this case specifically you need an INNER JOIN. Joins connects two tables together based on criteria you specify (such as matching values in fields) and merges the result into one table in the output.
Here's an example to suit your scenario:
SELECT
A.CardNumber,
A.LastName,
A.FirstName,
A.CustomerID,
B.DataItem
FROM
TableA A
INNER JOIN TableB B -- join tableB onto tableA
ON A.RecordID = B.RecordID -- in the ON clause you specify criteria by you match the fields
WHERE
B.columnA = 'CompanyA'
AND B.columnB = 1
Here's the relevant SQL Server Documentation
Also I'd advise you to potentially take a comprehensive introductory SQL tutorial, and/or find a book. A good one will introduce all of the basic, key concepts such as this to you in a logical way, then you're not grasping in the dark trying to google things for which you don't know the correct terminology.
select a.CardNumber, a.LastName, a.FirstName, a.CustomerID, b.dataitem
from tableA A inner join TableB b
on a.recordid = b.recordid
where b.columnA= 'CompanyA' and b.columnB = 1
Here is your solution,
select a.CardNumber, a.LastName, a.FirstName, a.CustomerID, b.DataItem from
tableA a
inner join tableB b
on (a.RecordID = b.RecordID)
where
b.DataItem='CompanyA'
b.RecordID=1;
Le me know if the result is not as expected
Your question is quite hard to understand, but let me give you an example that resembles the what i think you are asking.
SELECT a.*, b.DataItem FROM A a INNER JOIN B b
ON a.RecordID = b.RecordID AND
b.DataItem = `CompanyA`
At the database engine level, if you are using Microsoft technology, the most efficient structure is to use an indexed foreign key constraint on Table B, and a Primary Surrogate Key (PSK) column on Table A. The Primary Surrogate Key in your case is on the Parent table, Table A, and is called RecordID. The foreign key column with the FKC is on Table B, on the column named RecordID. Once you verify that there is a FKC (foreign key constraint on Table B, which pins both columns named RecordID between both tables on matched values), then address the GUI. At the GUI, between the tabs, you generally indicate you have a parent table with a unique set of Record IDs (one column named Record ID with absolutely unique values in each row and no empty rows on that column). There will also be child tables on each Tab in your GUI, and those are bound to the parent table in a "1 to Many (1:M)" fashion, where 1 parent has many children. Your commentary or question indicates that you also want to filter, where Record ID on the child in one of the related tabs equates to the integer value 1 on the Record ID. So, there needs to be a query somewhere:
SELECT [columns]
FROM [Table B]
INNER JOIN [Table A]
ON A.RecordID = B.RecordID
AND B.RecordID = 1;
Does that help?

Merge two versions of database tables with conflicting keys

I have been asked to merge 2 Access databases. They are conflicting versions of the same file.
A database was emailed to somebody. (I know.) Somebody added records to the 'main' copy while somebody else added records to their copy. I want to add the new records from the 'unauthorised' copy into the main version, before utterly destroying all other copies.
Unfortunately, the database has several related tables. As would naturally happen when records are added, records in different versions have conflicting primary keys. These conflicting keys are also used as foreign keys in the new records. A foreign key reference to ID x means different things in the 2 versions.
Is there any hope? I thought of maybe importing it all into excel and using formulas to update the primary and foreign keys.
Is there any way to fix this programatically?
EDIT: Here is a picture showing the full relationships. Tables teachers, tests, and test_results have been changed; the others are the same in both.
In the main database, add a Long field named [oldID] to each table into which you need to append data. Then create Linked Tables pointing to the relevant tables in the "other" database. Since the table names are the same, the linked tables will have a '1' appended to them.
For this example, we have
[teachers]
ID teacher oldID
-- -------- -----
1 TeacherA
2 TeacherB
3 TeacherX
[teachers1]
ID teacher
-- --------
1 TeacherA
2 TeacherB
3 TeacherY
[tests]
ID test_name teacher oldID
-- -------------- ------- -----
1 TeacherA_Test1 1
2 TeacherA_Test2 1
3 TeacherB_Test1 2
4 TeacherX_Test1 3
[tests1]
ID test_name teacher
-- -------------- -------
1 TeacherA_Test1 1
2 TeacherA_Test2 1
3 TeacherB_Test1 2
4 TeacherY_Test1 3
5 TeacherY_Test2 3
Make a note of where the tables diverge. In this case the [teachers] tables diverge after ID=2. So, insert the new rows from [teachers1] into [teachers], putting [teachers1].[ID] into [teachers].[oldID] so we can map old IDs to new ones:
INSERT INTO [teachers] ([teacher], [oldID])
SELECT [teacher], [ID] FROM [teachers1] WHERE [ID]>2
So now we have
[teachers]
ID teacher oldID
-- -------- -----
1 TeacherA
2 TeacherB
3 TeacherX
4 TeacherY 3
Now when we append the new rows from [tests1] into [tests] we can use an INNER JOIN on [teachers].[oldID] to adjust the foreign key values that get inserted:
INSERT INTO [tests] ([test_name], [teacher], [oldID])
SELECT [tests1].[test_name], [teachers].[ID], [tests1].[ID]
FROM [tests1] INNER JOIN [teachers] ON [tests1].[teacher]=[teachers].[oldID]
giving us
[tests]
ID test_name teacher oldID
-- -------------- ------- -----
1 TeacherA_Test1 1
2 TeacherA_Test2 1
3 TeacherB_Test1 2
4 TeacherX_Test1 3
5 TeacherY_Test1 4 4
6 TeacherY_Test2 4 5
Notice how the [teacher] foreign key has been mapped from the value 3 in [tests1] to 4 in [tests], reflecting the new [teachers].[ID] value for 'TeacherY'.
You can then repeat the process for child tables of [tests].
(Once the cleanup is complete you can remove the table links and drop the [oldID] columns.)
Is there any way to fix this programatically?
No. This must be done by a human capable of reading and understanding the data and taking decisions.
Create a query with an inner join between table one and table two, another query with an outer join between table one and table two, and another query with an outer join between table two and table one.
Now you can study the differences and decide which version of similar records to be kept and which records are completely new and should be kept - some with a new Primary Key.

How would I combine 2 distinct tables into 1 table in SSIS?

Say I have 2 distinct tables in SSIS from 2 different servers.
Table 1 Table 2
Animal Age Owner Location
Dog 10 Bill IL
Dog 7 Kelly CA
Cat 4 Tom TX
I want to have one single result table that is
Result Table
Animal Age Owner Location
Dog 10 NULL NULL
Dog 7 NULL NULL
Cat 4 NULL NULL
NULL NULL Bill IL
NULL NULL Kelly CA
NULL NULL Tom TX
a UNION should fit:
select animal, age, null as owner, null as location from animal
union
select null as animal, null as age, owner, location from owner
If you want to join two datasets without any join logic (No key in common) you need to:
Create a fake key column in each dataset (With derived column for exemple, value of the fake column should be different in each dataset)
Sort these fake key columns
Use a full outer join merge based on these fake relations
You make think it's a weird way to do, that is because it's a weird result you are trying to obtain, maybe could you explain your initial need ?
You should use merge component from SSIS tools. If you want FULL OUTER JOIN you will choose that in the editor of component.
But first of all you need to go to the Input and Output Properties tab and in the OLE DB Source Output set the IsSorted property value to True.(You need to make sure that the input data is truly sorted though.)

Creating a SQL view that contains columns which have different data types

I am trying to create a SQL view which contains columns from different tables; the columns are different data types.
For example;
I have table a with a column that contains usernames. The data type of this column is nvarchar.
I then have table b, which has a column that contains whether a document was printed in colour or not – the data is either yes or no. The data type of this column is bit.
I want the view to show both the above columns side by side, so I can then pull the information into Excel for reporting purposes.
I am pretty new to SQL so I am learning as I go along.
Like PM77-1 said, you'll have to have some way to tie the two tables together. For example, if your table b also has the userID of the person who printed the document out, your tables would look like this:
Table A Table B
---------------------------- -----------------------------------
userID userName docID docName inColor userID
---------------------------- -----------------------------------
1 userName1 1 docName1 1 1
2 userName2 2 docName2 0 2
3 userName3 1 docName1 1 2
3 docName3 0 1
3 docName3 1 2
2 docName2 1 3
and your query could look like this:
SELECT a.userName, b.docName, b.inColor FROM a INNER JOIN b ON a.userID = b.userID ORDER BY a.userName, b.inColor;

Getting matching attributes from two tables

I have two tables looking like this:
A B
id_attr value id id_attr value
-------------- -------------------
1 a 1 2 b
2 b 1 3 c
3 c 2 2 b
4 NULL 2 4 d
2 5 e
3 1 aaa
3 3 c
Table A is my reference table and I have multiple entries in table B. (every group of entries with the same id cosists of pairs of (id_attr,value) similiar to structure of table A). Goal is to check if entry in table A matches any of the entries in table B (one or more). One entry matches another when every attribute existing in table B under one id matches similiar attributes in table A. Also, in table A values could be NULL, but in table B not.
In example above my query should return "1", becouse only entries with id 1 fully match similiar entries in table A. Id 2 doesn't match, becouse in table A value of attribute 4 is NULL and it has an attribute which doesn`t exist in table A. Id 3 doesn't match either even if attribute 3 is similiar, but attribute 1 doesn't match.
As you can see to achieve a match not every one of the entries existing in table A should be matching, but if an attribute exists in table B then it value has to match similiar value in table A.
What is the most efficient way to achieve this result in an Oracle query?
Every help would be greatly appreciated. I can provide answers to further questions if I didn't express myself clear enough.
You can try the following:
SELECT ID, MIN(IS_OK) FROM
(
SELECT B.ID ID,
DECODE(B.VALUE, A.VALUE, 'Y', 'N') IS_OK
FROM A INNER JOIN B
ON B.ID_ATTR = A.ID_ATTR
)
GROUP BY ID;
Which will return you B's ID and a flag that indicates whether this ID is OK or not.
(Note that Decode will properly take care of the null values comparison without having to test for null values)