Create new table from current table inner joining 6 tables - sql

I am very new to SQL, so I apologize in advance if my query doesn't look perfect. I am trying to create a new table for this statement. I have 6 tables joined on the primary key. I tried Create table as (but it does not work). If anyone could please me, it would be greatly, greatly appreciated!
SELECT *
FROM DATABASE.Table1
INNER JOIN DATABASE.Table2
ON DATABASE.Table1.PrimaryKey = DATABASE.Table2.PrimaryKey
INNER JOIN DATABASE.Table3
ON DATABASE.Table1.PrimaryKey = DATABASE.Table3.PrimaryKey
INNER JOIN DATABASE.Table4
ON DATABASE.Table1.PrimaryKey = DATABASE.Table4.PrimaryKey
INNER JOIN DATABASE.Table5
ON DATABASE.Table1.PrimaryKey = DATABASE.Table5.PrimaryKey
INNER JOIN DATABASE.Table6
ON DATABASE.Table1.PrimaryKey = DATABASE.Table6.PrimaryKey
WHERE PrimaryKey = ‘1’

So you want one table with all the fields from each of the source tables, is that right? You can use a SELECT.... INTO:
SELECT [Field List] INTO MyNewConsolidatedTable
FROM DATABASE.Table1
INNER JOIN DATABASE.Table2
ON DATABASE.Table1.PrimaryKey = DATABASE.Table2.PrimaryKey
INNER JOIN DATABASE.Table3
ON DATABASE.Table1.PrimaryKey = DATABASE.Table3.PrimaryKey
INNER JOIN DATABASE.Table4
ON DATABASE.Table1.PrimaryKey = DATABASE.Table4.PrimaryKey
INNER JOIN DATABASE.Table5
ON DATABASE.Table1.PrimaryKey = DATABASE.Table5.PrimaryKey
INNER JOIN DATABASE.Table6
ON DATABASE.Table1.PrimaryKey = DATABASE.Table6.PrimaryKey
WHERE PrimaryKey = ‘1’
Note that you will need to replace [Field List] and enumerate all of the fields that you want in the new table, because otherwise you'll have 6 fields called PrimaryKey, which SQL won't allow.

Related

Is it possible to have multiple joins between two tables in stored procedure?

I have two tables, "Booking" and "City". CityName field is primary key in City table and I have used it as foreign key for two columns "SourceCity" and "DestinationCity" in Booking table. I want to create a stored procedure to select all existing data from the Booking table for creating a view list, for which I have written the following.
SELECT [dbo].[Booking].[BookingID],
[dbo].[Booking].[CustomerName],
[dbo].[City].[CityName],
[dbo].[City].[CityName],
[dbo].[Booking].[StartingDate],
[dbo].[Booking].[EndingDate],
[dbo].[Car].[LicensePlateNumber],
[dbo].[Driver].[DriverName],
[dbo].[Booking].[AdvanceTaken],
[dbo].[Booking].[PendingPayment],
[dbo].[Booking].[TotalRent],
[dbo].[Booking].[BookingDate],
[dbo].[Booking].[IDProof]
FROM [dbo].[Booking]
**LEFT OUTER JOIN [dbo].[City]
ON [dbo].[Booking].[SourceCity] = [dbo].[City].[CityName]
AND [dbo].[Booking].[DestinationCity] = [dbo].[City].[CityName]**
LEFT OUTER JOIN [dbo].[Driver]
ON [dbo].[Driver].[DriverID] = [dbo].[Booking].[DriverAllotted]
LEFT OUTER JOIN [dbo].[Car]
ON [dbo].[Car].[CarID] = [dbo].[Booking].[CarAllotted]
ORDER BY [dbo].[Booking].[BookingID]
I am not sure if it is possible to do the following
LEFT OUTER JOIN [dbo].[City]
ON [dbo].[Booking].[SourceCity] = [dbo].[City].[CityName]
AND [dbo].[Booking].[DestinationCity] = [dbo].[City].[CityName]
I guess you need a different JOIN
FROM [dbo].[Booking] as booking
LEFT OUTER JOIN [dbo].[City] as source_city
ON booking.[SourceCity] = source_city.[CityName]
LEFT OUTER JOIN [dbo].[City] as destination_city
ON booking.[DestinationCity] = destination_city.[CityName]
....
Yes it is possible, you just need to use a different table alias. Beyond referencing the same table twice, table aliases can make your code look a lot cleaner, e.g.
SELECT b.CustomerName,
sc.CityName AS SourceCity,
dc.CityName AS DestinationCity,
b.StartingDate,
b.EndingDate,
c.LicensePlateNumber,
d.DriverName,
b.AdvanceTaken,
b.PendingPayment,
b.TotalRent,
b.BookingDate,
b.IDProof
FROM dbo.Booking AS b
LEFT OUTER JOIN dbo.City AS sc
ON sc.CityName= b.SourceCity
LEFT OUTER JOIN dbo.City AS dc -- Different Alias here
ON dc.CityName = b.DestinationCity
LEFT OUTER JOIN dbo.Driver AS d
ON d.DriverID = b.DriverAllotted
LEFT OUTER JOIN dbo.Car AS c
ON c.CarID = b.CarAllotted
ORDER BY
b.BookingID;
I appreciate that cleaner is somewhat subjective, but I would be astonished if anyone found this harder to read than your original query

why I get different number of records when using LEFT JOIN

I need to join many to many relationship. In order to do that I am using
LEFT OUTER JOIN
(SELECT
SICCode, QuoteID
FROM
NetRate_Quote_Insur_Quote_Busin
WHERE
QuoteID IN
(SELECT DISTINCT QuoteID
FROM NetRate_Quote_Insur_Quote_Busin)) nr ON nr.QuoteID = tblQuotes.QuoteID
The goal is to bring the column SICCode. For that, I am using DISTINCT statement to make relationship many to one. But for some reason I got different number of records.
The last LEFT OUTER JOIN is the one that I am stuck with
Full query looks like this:
SELECT
MONTH(INV.EffectiveDate) AS Effective_Month,
tblQuotes.PolicyNumber,
YEAR(INV.EffectiveDate) AS Effective_Year,
INV.EffectiveDate,
INV.[InvoiceDate] as [Billed Date],
tblQuotes.ExpirationDate as [Policy Expiration Date],
INV.DueDate,
dbo.tblFin_InvoiceDetails.AmtBilled AS Written
FROM
tblClientOffices
INNER JOIN
tblInsureds (NOLOCK)
INNER JOIN
tblFin_Invoices INV
INNER JOIN
tblFin_InvoiceDetails ON INV.InvoiceNum = dbo.tblFin_InvoiceDetails.InvoiceNum
INNER JOIN
tblCompanyLines (NOLOCK) ON dbo.tblFin_InvoiceDetails.CompanyLineGuid = dbo.tblCompanyLines.CompanyLineGUID
INNER JOIN
lstLines (NOLOCK) ON dbo.tblCompanyLines.LineGUID = dbo.lstLines.LineGUID
AND dbo.tblCompanyLines.LineGUID = dbo.lstLines.LineGUID
INNER JOIN
tblProducerLocations (NOLOCK) ON INV.ProducerLocationGUID = tblProducerLocations.ProducerLocationGUID
ON tblInsureds.InsuredGUID = INV.InsuredGUID
INNER JOIN
tblQuotes (NOLOCK) ON INV.QuoteID = tblQuotes.QuoteID
AND INV.QuoteControlNum = tblQuotes.ControlNo
INNER JOIN
lstPolicyTypes (NOLOCK) ON tblQuotes.PolicyTypeID = lstPolicyTypes.PolicyTypeID
INNER JOIN
tblSubmissionGroup (NOLOCK) ON tblQuotes.SubmissionGroupGuid = tblSubmissionGroup.SubmissionGroupGUID
INNER JOIN
tblCompanyLocations (NOLOCK) ON tblQuotes.CompanyLocationGuid = tblCompanyLocations.CompanyLocationGUID
INNER JOIN
tblUsers (NOLOCK) ON INV.UnderwriterUserGUID = tblUsers.UserGUID
ON tblClientOffices.OfficeGUID = tblQuotes.IssuingLocationGuid
LEFT OUTER JOIN
tblUsers tblUsers_1 (NOLOCK) ON tblSubmissionGroup.InHouseProducerUserGuid = tblUsers_1.UserGUID
LEFT OUTER JOIN
(SELECT SICCode, QuoteID
FROM NetRate_Quote_Insur_Quote_Busin
WHERE QuoteID IN
(SELECT DISTINCT QuoteID
FROM NetRate_Quote_Insur_Quote_Busin)) nr ON nr.QuoteID = tblQuotes.QuoteID
WHERE
(tblInsureds.TestInsured = 0)
AND (INV.Failed = 0)
AND (tblFin_InvoiceDetails.ChargeType = 'p')
ORDER BY
YEAR(INV.EffectiveDate),
MONTH(INV.EffectiveDate),
lstLines.LineID
What would be the trick to bring Column SICCode and keep the same number of records?
I also tried to do this:
LEFT OUTER JOIN NetRate_Quote_Insur_Quote_Busin nr ON nr.QuoteID =
(
SELECT distinct QuoteID from NetRate_Quote_Insur_Quote_Busin
where QuoteID =tblQuotes.QuoteID
)
But it gives me more records than it should be
Also tried this one:
LEFT OUTER JOIN
( SELECT TOP 1 SICCode, QuoteID
FROM NetRate_Quote_Insur_Quote_Busin
WHERE QuoteID IN
(SELECT DISTINCT QuoteID
FROM NetRate_Quote_Insur_Quote_Busin)order by QuoteID desc ) nr ON nr.QuoteID = tblQuotes.QuoteID
But doesnt bring me any SICCode
DISTINCT will not change a many to many relationship to a many to one. It looks like your data has many SICCode values to one QuoteID which is why you getting higher record counts.
You could use a window function like Rank, but this is an arbitrary selection.
You could try to pivot/unpivot the SICCode column, but that would give you 1 column for each possible value, which would not work if you have a large number of unique values in the column.
A final option is to create a new table which has a QuoteID column and a SICCodes column, then populate it withSICCodes being a comma seperated list of the codes.
In conclusion, there is no easy way to change a many to many relationship to a many to one relationship unless you are willing to lose data or there are only a few values.

Adding a condition to an inner join query in Oracle

I have this inner join query:
select *
from ioa_invoice_line
INNER JOIN ioa_invoice
ON ioa_invoice_line.invo_id = ioa_invoice.id ;
Now, I want to add this condition also in the above inner join that is
where ioa_invoice_line.invo_id =234
Please advise how to add this condition in above query.
As Felix says in his comment you can add it without problems:
select *
from ioa_invoice_line
INNER JOIN ioa_invoice
ON ioa_invoice_line.invo_id = ioa_invoice.id
AND ioa_invoice_line.invo_id = 234
As this is criteria on the first table, you would usually simply add this WHERE clause at the end of your query (before the semicolon of course).
However, you are dealing with an invoice table and its detail table here and the criteria is on the key linking the tables. So for readability, I would swap the tables and name the parent table first and join the child table. That feels more natural:
select *
from ioa_invoice i
join ioa_invoice_line il on il.invo_id = i.id
where i.id = 234;
select * from
ioa_invoice_line il
INNER JOIN ioa_invoice i
ON il.invo_id = i.id
where il.invo_id = 234
This format use as a professional practice

Joining multiple tables to one table in sql

I have a rather complex (well for me) sql query happening and I am having trouble with some concepts.
I have the following sql on a webpage that i am building
SELECT
[dbo].[Enrolment].[_identity], [dbo].[Enrolment].CommencementDate,
[dbo].[Enrolment].CompletionDate, [dbo].[Enrolment].enrolmentDate,
[dbo].[Course].name coursename, [dbo].[Course].Identifier as QUALcode,
[dbo].[Person].givenName, [dbo].[Person].Surname,[dbo].[Employer].name as empname,
[dbo].[Employer].Address1,[dbo].[Employer].Suburb,[dbo].[Employer].Phone,
[dbo].[Employer].PostCode,[dbo].[EnrolmentStatus].name as enrolname,
[dbo].[Student].identifier,[dbo].[Student].person,[dbo].[Contact].person as CONTACTid
FROM
(((([dbo].[Enrolment]
LEFT JOIN
[dbo].[Course] ON [dbo].[Enrolment].course = [dbo].[Course].[_identity])
LEFT JOIN
[dbo].[Employer] ON [dbo].[Enrolment].employer = [dbo].[Employer].[_identity])
LEFT JOIN
[dbo].[EnrolmentStatus] ON [dbo].[Enrolment].status = [dbo].[EnrolmentStatus].[_identity])
LEFT JOIN
[dbo].[Student] ON [dbo].[Enrolment].student = [dbo].[Student].[_identity])
LEFT JOIN
[dbo].[Person] ON [dbo].[Student].person = [dbo].[Person].[_identity]
LEFT JOIN
[dbo].[Contact] ON [dbo].[Employer].[_identity] = [dbo].[Contact].employer
WHERE
(([dbo].[EnrolmentStatus].name) = 'training'
OR
([dbo].[EnrolmentStatus].name) = 'enrolled')
This is working fine but what I would like to do is join to the [dbo].[Person] table again but this time joining from another table so the code I effectively need to patch into the above statement is
LEFT JOIN
[dbo].[Trainer] ON [dbo].[Enrolment].Trainer = [dbo].[Trainer].[_identity])
LEFT JOIN
[dbo].[Person] ON [dbo].[Trainer].person = [dbo].[Person].[_identity]
I then need to be able to get from the person table the name of the student and the name of the trainer, so I need 2 records from the person table for every record from the Enrolment table, the fields I need from the person table are the same for both trainer and student in that I am trying to get the given name and surname for both.
Any help or pointers would be most appreciated.
You have to just use replace your from clause with this. You have to just first use the Trainer table join, then Person table, then use the AND keyword to use multiple mapping with single table
FROM (((([dbo].[Enrolment]
LEFT JOIN [dbo].[Course] ON [dbo].[Enrolment].course = [dbo].[Course].[_identity])
LEFT JOIN [dbo].[Employer] ON [dbo].[Enrolment].employer = [dbo].[Employer].[_identity])
LEFT JOIN [dbo].[EnrolmentStatus] ON [dbo].[Enrolment].status = [dbo].[EnrolmentStatus].[_identity])
LEFT JOIN [dbo].[Student] ON [dbo].[Enrolment].student = [dbo].[Student].[_identity])
LEFT JOIN [dbo].[Trainer] ON [dbo].[Enrolment].Trainer = [dbo].[Trainer].[_identity])
LEFT JOIN [dbo].[Person] ON [dbo].[Student].person = [dbo].[Person].[_identity]
AND [dbo].[Trainer].person = [dbo].[Person].[_identity]
LEFT JOIN [dbo].[Contact] ON [dbo].[Employer].[_identity] = [dbo].[Contact].employer
Use aliasing like this..
LEFT JOIN [dbo].[Trainer] ON [dbo].[Enrolment].Trainer = [dbo].[Trainer].[_identity])
LEFT JOIN [dbo].[Person] AS p ON [dbo].[Trainer].person = p.[_identity]
If I get your question right - what you are trying to do is to join the same table twice in your SQL. You have one table Person which has both student and trainer information and you want to see their details side by side in your result set. So you need to join Person once with Student and another time with Trainer
To do this - you will have to join Person table together. Give your tables an alias like the other answers have suggested. Then your FROM clause can look like this -
FROM (((([dbo].[Enrolment]
LEFT JOIN [dbo].[Course] ON [dbo].[Enrolment].course = [dbo].[Course].[_identity])
LEFT JOIN [dbo].[Employer] ON [dbo].[Enrolment].employer = [dbo].[Employer].[_identity])
LEFT JOIN [dbo].[EnrolmentStatus] ON [dbo].[Enrolment].status = [dbo].[EnrolmentStatus].[_identity])
LEFT JOIN [dbo].[Student] ON [dbo].[Enrolment].student = [dbo].[Student].[_identity])
LEFT JOIN [dbo].[Person] P1 ON [dbo].[Student].person = P1.[_identity]
LEFT JOIN [dbo].[Contact] ON [dbo].[Employer].[_identity] = [dbo].[Contact].employer
LEFT JOIN [dbo].[Trainer] ON [dbo].[Enrolment].Trainer = [dbo].[Trainer].[_identity])
LEFT JOIN [dbo].[Person] P2 ON [dbo].[Trainer].person = P2.[_identity]
....
....
Here P1 and P2 are two aliases for [Person]

Joining multiple tables and getting multiple attributes from one of them

I'm trying to join multiple tables together for building a report. The report lists a course, revisions made to it, and who requested, made and approved the revisions.
Under requested, made an approved, the values are employee numbers. I'm trying to join my innerjoined table above, with the Employee table so I can list the names (not just employee numbers) of those that requested, made and approved revisions.
This is what I have which I know is totally wrong.
SELECT *
FROM Courses
INNER JOIN CourseRevisions ON CourseRevisions.PELID = Courses.PELID
INNER JOIN CourseGroups ON CourseGroups.CourseGroupID = Courses.CourseGroupID
INNER JOIN [dbo].[OPG_Employees] ON OPG_Employees.EmployeeID = CourseRevisions.UpdatedBy
AND OPG_Employees.EmployeeID = CourseRevisions.ApprovedBy
AND OPG_Employees.EmployeeID = CourseRevisions.RequestedBy
This only returns a single result which just happens to have the same employee ID listed for all 3 (Requested, Approved and Updated)
How would i get it so I can get the table result for individual employees in each?
You have to join to the OPG_Employees table once for each field, i.e. 3 times in the example above. One INNER JOIN to it for UpdatedBy, one INNER JOIN for ApprovedBy, one INNER JOIN for RequestedBy.
Something like so:
SELECT *
FROM Courses
INNER JOIN CourseRevisions ON CourseRevisions.PELID = Courses.PELID
INNER JOIN CourseGroups ON CourseGroups.CourseGroupID = Courses.CourseGroupID
INNER JOIN [dbo].[OPG_Employees] empUpdatedBy ON empUpdatedBy.EmployeeID = CourseRevisions.UpdatedBy
INNER JOIN [dbo].[OPG_Employees] empApprovedBy ON empApprovedBy.EmployeeID = CourseRevisions.ApprovedBy
INNER JOIN [dbo].[OPG_Employees] empRequestedBy ON empRequestedBy.EmployeeID = CourseRevisions.RequestedBy
You need a separate join for each employee being referenced:
SELECT *
FROM Courses INNER JOIN
CourseRevisions
ON CourseRevisions.PELID = Courses.PELID INNER JOIN
CourseGroups
ON CourseGroups.CourseGroupID = Courses.CourseGroupID INNER JOIN
[dbo].[OPG_Employees] UpdateEmp
ON UpdateEmp.EmployeeID = CourseRevisions.UpdatedBy INNER JOIN
[dbo].[OPG_Employees] ApprovedEmp
on OPG_ApprovedEmp.EmployeeID = CourseRevisions.ApprovedBy INNER JOIN
[dbo].[OPG_Employees] RequestedEmp
on RequestedEmp.EmployeeID = CourseRevisions.RequestedBy
Your original formulation required that all three ids be exactly the same.