One to Many Database Table Relationship - sql-server

I do have two tables from the database..
Consultation Table
-ConsultationNo -PK
-PatientNo -FK
-Diagnosis
-Etc...
VitalSign Table
-VitalSignNo -PK
-Weight
-Height
-HeartRate
-BloodPressure
-Etc
I need to join these two tables like this..
Consultation Table
-ConsultationNo -PK
-PatientNo -FK
**-VitalSignNo** -FK
-Diagnosis
-Etc...
But sometimes, my VitalSign Table will not accept any values, therefore the relationship between those two tables would not be enforced, what should I do?

Use an outer join like so...
Select * from Consultation
Left join VitalSign on (Consultation.ConsultationNo = vitalsign.ConsultationNo)
You will get all rows from consultation, and the matching rows from Vitalsign. When there are no rows in Vitalsign all those columns will come back null, but you will still get the consultation rows.
This might not be exactly right for your situation because the table structure in your question doesn't look complete. That, is you didn't have a foreign key in either table referencing the PK of the other.

Related

Join two one-to many tables on different databases to compare the many items

I have two tables on two databases on same server, each with a one to many relationship on the Asset/Equipment. I need to compare the Asset/Equipment in the two databases.
Here are the tables on one database-
Database 1:
Table1:
Application - one
-APP_KEY primary key
Table2:
Asset - many
-AS_APP_FKEY foreign key
-SampleAsset1
-SampleAsset2
-SampleAsset3
Database 2:
Table3:
Application - one
-ApplicationId primary key
-App_Key nullable, this ends up being the APP_KEY on database 1
Table4:
Equipment - many
-EquipID primary key
-ApplicationId foreign key of application
-SampleEquip1
-SampleEquip2
-SampleEquip3
Is there a way to make a query to show SampleEquip1 next to sampleAsset1 based on these relationships.
Edit:
This is the query I have tried but it creates duplicate items. For example if there is four items in each child table it creates 8 comparison rows with duplicates and distinct doesn't remove the duplicates.
SELECT app.APP_KEY,
e.SampleEquip1,
secondDb.APP_KEY,
secondDb.SampleAsset1
FROM dabatase1.dbo.Application app
JOIN database1.dbo.Equipment e
ON e.ApplicationId = app.ApplicationId
LEFT JOIN(
SELECT ap.APP_KEY,
a.SampleAsset1
FROM database2.dbo.Application ap
JOIN database2.dbo.Asset a
ON a.AS_APP_FKEY = ap.APP_KEY
) secondDb
ON secondDb.APP_KEY = app.APP_KEY
WHERE app.APP_KEY = 123

how to use case to combine spelling variations of an item in a table in sql

I have two SQL tables, with deviations of the spellings of department names. I'm needing to combine those using case to create one spelling of the location name. Budget_Rc is the only one with same spelling in both tables. Here's an example:
Table-1 table-2
Depart_Name Room_Loc Depart_Name Room_Loc
1. Finance_P1 P144 1. Fin_P1 P1444
2. Budget_Rc R2c 2. Budget_Rc R2c
3. Payroll_P1_2 P1144 3. Finan_P1_1 P1444
4. PR_P1_2 P1140
What I'm needing to achieve is for the department to be 1 entity, with one room location. These should show as one with one room location in the main table (Table-1).
Depart_Name Room_Loc
1. Finance_P1 F144
2. Budget_Rc R2c
3. Payroll_P1_2 P1144
Many many thanks in advance!
I'd first try a
DECLARE #AllSpellings TABLE(DepName VARCHAR(100));
INSERT INTO #AllSpellings(DepName)
SELECT Depart_Name FROM tbl1 GROUP BY Depart_Name
UNION
SELECT Depart_Name FROM tbl2 GROUP BY Depart_Name;
SELECT DepName
FROM #AllSpellings
ORDER BY DepName
This will help you to find all existing values...
Now you create a clean table with all Departments with an IDENTITY ID-column.
Now you have two choices:
In case you cannot change the table's layout
Use the upper select-statement to find all existing entries and create a mapping table, which you can use as indirect link
Better: real FK-relation
Replace the department's names with the ID and let this be a FOREIGN KEY REFERENCE
Can more than one department be in a Room?
If so then its harder and you can't really write a dynamic query without having a list of all the possible one to many relationships such as Finance has the department key of FIN and they have these three names. You will have to define that table to make any sort of relationship.
For instance:
DEPARTMENT TABLE
ID NAME ROOMID
FIN FINANCE P1444
PAY PAYROLL P1140
DEPARTMENTNAMES
ID DEPARTMENTNAME DEPARTMENTID
1 Finance_P1 FIN
2 Payroll_P1_2 PAY
3 Fin_P1 FIN
etc...
This way you can correctly match up all the departments and their names. I would use this match table to get the data organized and normalized before then cleaning up all your data and then just using a singular department name. Its going to be manual but should be one time if you then clean up the data.
If the room is only ever going to belong to one department you can join on the room which makes it a lot easier.
Since there does not appear any solid rule for mapping department names from table one to table two, the way I would approach this is to create a mapping table. This mapping table will relate the two department names.
mapping
Depart_Name_1 | Depart_Name_2
-----------------------------
Finance_P1 | Fin_P1
Budget_Rc | Budget_Rc
Payroll_P1_2 | PR_P1_2
Then, you can do a three-way join to bring everything into a single result set:
SELECT t1.*, t2.*
FROM table1 t1
INNER JOIN mapping m
ON t1.Depart_Name = m.Depart_Name_1
INNER JOIN table2 t2
ON m.Depart_Name_2 = t2.Depart_Name
It may seem tedious to create the mapping table, but it may be unavoidable here. If you can think of a way to automate it, then this could cut down on the time spent there.

transfer data from one database to another regarding keys

How can i transfer rows from two tables (Patient and ContactDetails) from DB1 to DB2?
Both DBs, have already these 2 tables with data. i just want to add data from these two tables from db1 to db2.
i tried following that
but it didnt work, because there are some rows with the same keys and overwrite is forbidden.
is there an other way to do it? or am i missing something?
patient and contactdetails relationship is
patient inner join contactdetails
(foreign_key)patient.contactdetailsid = (primary_key)contactdetails.id
loop on the source contactdetails table, insert each row one a time saving in a temp table the old contactdetail id and the matching new contactdetail id (here is an example of sql loop).
the temp table should be something like:
create #temptableforcopy table (
oldcontactdetailsid [insertheretherightdatatype],
newcontactdetailsid [insertheretherightdatatype]
)
copy the data from the patient table joined to the temp table used for the previous step like this:
insert into newdb.newschema.patient (contactdetailsid, field1, field2, ...)
select TT.newcontactdetailsid,
old.field1,
old.field2,
...
from olddb.oldschema.patient old
join #temptableforcopy TT on TT.oldcontactdetailsid = old.contactdetailsid
please note that my proposal is just a wild guess: you gave no information about structure, keys, constraints, no detail about which key is preventing the copy with which error message, the solution you already discarded, the amount of data you have to deal with...

Selecting multiple rows of many to many related columns into one column in SQL SERVER?

I have the following DB Tables with SQL Server
Booking(bookingID,customerName,branchID,RefNumber,...)
Trip(TripID,vehicleID,...)
BookingToTripMap(TripID,bookingID)
Branch(branchID, branchName)
Vehicle(vehicleID,vehicleNumber)
There is a one to one relationship between (Booking,Branch) and (Trip, Vehicle) and Many to many relationship between Booking, Trip which is saved in the table BookingToTripMap.
Now I want to extract a query that would return the following
Booking.RefNumber Booking.CustomerName Vehicle.VehicleNumber
(All vehicle numbers in one cell)
Here is your query
SELECT B.RefNumber, B.CustomerName, V.VehicleNumber
FROM ((Booking AS B INNER JOIN BookingToTripMap AS BT
ON B.bookingID = BT.bookingID) INNER JOIN TRIP as T
ON T.TripID = BT.TripID) INNER JOIN Vehicle as V
ON V.vehicleID = T.vehicleID
I would add the field bookingID to the table Trip, it seems that the table BookingToTripMap doesn't add any value to your database.
Also, if your vehicle's numbers are unique, you could change the primary key in the Vehicle table to vehicleNumber, and change the same columns in the Trip table. Thus you could retrieve the vehicleNumber directly from the Trip table.
I'm just guessing in that, based on the given information.
Regards,

Recommended approach to merging two tables

I have a database schema like this:
[Patients] [Referrals]
| |
[PatientInsuranceCarriers] [ReferralInsuranceCarriers]
\ /
[InsuranceCarriers]
PatientInsuranceCarriers and ReferralInsuranceCarriers are identical, except for the fact that they reference either Patients or Referrals. I would like to merge those two tables, so that it looks like this:
[Patients] [Referrals]
\ /
[PatientInsuranceCarriers]
|
[InsuranceCarriers]
I have two options here
either create two new columns - ID_PatientOrReferral + IsPatient (will tell me which table to reference)
or create two different columns - ID_Patient and ID_Referral, both nullable.
Generally, I try to avoid nullable columns, because I consider them a bad practice (meaning, if you can live w/o nulls, then you don't really need a nullable column) and they are more difficult to work with in code (e.g., LINQ to SQL).
However I am not sure if the first option would be a good idea. I saw that it is possible to create two FKs on ID_PatientOrReferral (one for Patients and one for Referrals), though I can't set any update/delete behavior there for obvious reasons, I don't know if constraint check on insert works that way, either, so it looks like the FKs are there only to mark that there are relationships. Alternatively, I may not create any foreign keys, but instead add the relationships in DBML manually.
Is any of the approaches better and why?
To expand on my somewhat terse comment:
I would like to merge those two tables
I believe this would be a bad idea. At the moment you have two tables with good clear relation predicates (briefly, what it means for there to exist a record in the table) - and crucially, these relation predicates are different for the two tables:
A record exists in PatientInsuranceCarriers <=> that Patient is associated with that Insurance Carrier
A record exists in ReferralInsuranceCarriers <=> that Referral is associated with that Insurance Carrier
Sure, they are similar, but they are not the same. Consider now what would be the relation predicate of a combined table:
A record exists in ReferralAndPatientInsuranceCarriers <=> {(IsPatient is true and the Patient with ID ID_PatientOrReferral) or alternatively (IsPatient is false and the Referral with ID ID_PatientOrReferral)} is associated with that Insurance Carrier
or if you do it with NULLs
A record exists in ReferralAndPatientInsuranceCarriers <=> {(ID_Patient is not NULL and the Patient with ID ID_Patient) or alternatively (ID_Referral is not NULL and the Referral with ID ID_Referral)} is associated with that Insurance Carrier
Now, I'm not one to automatically suggest that more complicated relation pedicates are necessarily worse; but I'm fairly sure that either of the two above are worse than those they would replace.
To address your concerns:
we now have two LINQ to SQL entities, separate controllers and views for each
In general I would agree with reducing duplication; however, only duplication of the same things! Here, is it not the case that all the above are essentially 'boilerplate', and their construction and maintenance can be delegated to suitable development tools?
and have to merge them when preparing data for reports
If you were to create a VIEW, containing a UNION, for reporting purposes, you would keep the simplicity of the actual data and still have the ability to report on a combined list; eg (making assumptions about column names etc):
CREATE VIEW InterestingInsuranceCarriers
AS
SELECT
IC.Name InsuranceCarrierName
, P.Name CounterpartyName
, 'Patient' CounterpartyType
FROM InsuranceCarriers IC
INNER JOIN PatientInsuranceCarriers PIC ON IC.ID = PIC.InsuranceCarrierID
INNER JOIN Patient P ON PIC.PatientId = P.ID
UNION
SELECT
IC.Name InsuranceCarrierName
, R.Name CounterpartyName
, 'Referral' CounterpartyType
FROM InsuranceCarriers IC
INNER JOIN ReferralInsuranceCarriers RIC ON IC.ID = RIC.InsuranceCarrierID
INNER JOIN Referral R ON PIC.ReferralId = R.ID
Copying my answer from this question
If you really need A_or_B_ID in TableZ, you have two similar options:
1) Add nullable A_ID and B_ID columns to table z, make A_or_B_ID a computed column using ISNULL on these two columns, and add a CHECK constraint such that only one of A_ID or B_ID is not null
2) Add a TableName column to table z, constrained to contain either A or B. now create A_ID and B_ID as computed columns, which are only non-null when their appropriate table is named (using CASE expression). Make them persisted too
In both cases, you now have A_ID and B_ID columns which can have appropriate foreign
keys to the base tables. The difference is in which columns are computed. Also, you
don't need TableName in option 2 above if the domains of the 2 ID columns don't
overlap - so long as your case expression can determine which domain A_or_B_ID
falls into

Resources