How to join multiple tables in a view - sql

how to create view of this query anyone help me please, i want create view of this but its show me error
Msg 4506, Level 16, State 1, Procedure ordersview, Line 3 Column names
in each view or function must be unique. Column name 'ID' in view or
function 'ordersview' is specified more than once.
CREATE VIEW ordersview
AS
Select * from UserClaimData cd
Inner join UserClaimDeductions ud on
ud.CLAIMID = cd.ID
Inner join UserClaimApproval ua on
ua.CLAIMID = cd.ID
inner join ClaimDataBreakdown cb on
cb.CLAIMID = cd.ID
inner join AppExpenseTypes ae on
ae.ID = cb.EXPENSETYPE
inner join AppNOWTypes an on
ae.ID = an.EXPENSETYPEID
inner join AppAreas aa on
aa.ID = cb.AREAID
inner join AppZones az on
cb.ZONEID = az.ID
inner join AppRegions ar on
ar.ID = cb.REGIONID

The answer to the question you've asked is to specifically reference elements from each table; for example:
CREATE VIEW ordersview
AS
Select cd.ID AS ID1, ua.ID as ID2, etc... from UserClaimData cd
Inner join UserClaimDeductions ud on
ud.CLAIMID = cd.ID
Inner join UserClaimApproval ua on
ua.CLAIMID = cd.ID
inner join ClaimDataBreakdown cb on
cb.CLAIMID = cd.ID
inner join AppExpenseTypes ae on
ae.ID = cb.EXPENSETYPE
inner join AppNOWTypes an on
ae.ID = an.EXPENSETYPEID
inner join AppAreas aa on
aa.ID = cb.AREAID
inner join AppZones az on
cb.ZONEID = az.ID
inner join AppRegions ar on
ar.ID = cb.REGIONID
I would, however, suggest that you don't put such a complex join inside a view. Consider the columns you want, and perhaps think about a stored procedure, or a table value function.

What part of the error message do you not understand?
You have select *, which brings together all columns from all tables. Just based on the join conditions, it is clear that most tables have an ID column, so there are multiple columns called ID. CLAIMID also seems quite popular.
In general, using select * is discouraged. However, it should not be used for views. A view should state the columns that it contains:
select cd.Id, . . .

Your view has more than one column with the same name, and this is causing the error.
AppRegions has a column called ID
AppAreas has a column called ID
UserClaimData has a column called ID
Change the Select * to specify the columns of the tables you want to have on the View table, and put a particularry name, or just don't put them.
You need to change the name of some columns in the view. Use AppAreas.ID as aaID

A view is like a virtual table, So you can't have the same name for 2(or more) columns.
So to avoid this, in your select Query instead of * provide the column names, and if there are 2 columns with the same name and you need them both in the view, give them different alias names.
Suppose you have ColumnA in TableA and TableB and you want them both in the view. Create view like this
CREATE VIEW vm_Sample
SELECT
A.COLUMNA COLUMNA_1,
B.COLUMNA COLUMNA_2
FROM TABLEA A INNER JOIN TABLE B
ON A.ID = B.ID

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

Join tables when 3 column in first table that can point to same column in second table

I have the following DB structure:
And right now I can't make up a query to get
a creator data, admin data and tech data from item_contacts...
What kind of JOIN I need to use and how?
I think you want 3 joins on item_contacts - one for each column whose data you want to recover:
select
i.*,
cc.data as creator_data,
ca.data as admin_data,
ct.data as tech_data
from items i
inner join item_contacts cc on cc.contact_id = i.creator_id
inner join item_contacts ca on ca.contact_id = i.admin_id
inner join item_contacts ct on ct.contact_id = i.tech_id

Stacking ON clauses with INNER JOIN

I saw this join and I was wondering where this syntax comes from.
SELECT *
FROM [dbo].[AA]
INNER JOIN dbo.BB
INNER JOIN dbo.CC ON BB.ID = CC.BB_ID
ON AA.ID = BB.AA_ID
It is strange that I can only refer to tables BB and CC on the first ON clause and not to table AA.
Normally I write down first table name and then the join condition.
SELECT *
FROM [dbo].[AA]
INNER JOIN dbo.BB ON AA.ID = BB.AA_ID
INNER JOIN dbo.CC ON BB.ID = CC.BB_ID
My questions are what is the background of the first syntax and if there is any influence on the execution, so far I did not see it.
I believe all that is happening here is that the query is joining your CC table to your BB table rather than AA, as if it was a sub-query. If you change the layout of your query a little you will be able to see this nested joining in the same way you would a case expression:
select *
from [dbo].[AA]
inner join dbo.BB
inner join dbo.CC
on BB.ID = CC.BB_ID
on AA.ID = BB.AA_ID;

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]