I want to create a view that has 2 or more inner joins in Datagrip with Postgres. First of all, the following query has no problem executing:
select *
from student inner join participates t on student.matrnr = t.matrnr
inner join martin_classes mc on t.lvnr = mc.lvnr;
And this would be a sort of an intermediate result, so that's why I want to create it as a view. But when I try to execute this query:
create view martin_andAll as
select *
from student inner join participates t on student.matrnr = t.matrnr
inner join martin_classes mc on t.lvnr = mc.lvnr;
the following error occurs: [42701] ERROR: column "matrnr" specified more than once
an easy fix would be using the keyword USING instead of ON (condition)
but that only works if I'm having only one join.
So at the following query I get the exact same error as before:
create view martin_andAll as
select *
from student inner join participates t using (matrnr)
inner join martin_classes mc using (lvnr);
And just to be clear, this works just fine:
create view martin_andAll as
select *
from student inner join participates t using (matrnr);
So my question is, why doesn't it work with multiple joins and how can I overcome this?
Related
I have two scripts that work in isolation, but I don't know how to stitch them together to do this all at once.
The first script:
SELECT *
FROM PROD_ANALYTIC.SRC_MVC_AU_DBO.BCAPPLICATIONQUOTES bq
JOIN PROD_ANALYTIC.SRC_MVC_AU_DBO.PRODUCT p ON bq.ProductId = p.Id
JOIN PROD_ANALYTIC.SRC_MVC_AU_DBO.BCAPPLICATIONQUOTEFEES F ON F.ApplicationQuoteId = bq.Id
LEFT JOIN PROD_ANALYTIC.SRC_MVC_AU_DBO.COVERAGESECTIONTYPE CST ON F.CoverageSectionTypeID = CST.SECTIONID
This produces a table (is that the right word?). Suppose I could save that table as 'appQuote'. I then want to run this script on it:
SELECT
ApplicationId,
STRING_AGG(YEARLYPAYAMOUNT) allPremium,
STRING_AGG(SECTIONID) allSection,
STRING_AGG(SHORTNAME) allSectionName,
FROM
appQuote
GROUP BY
ApplicationId
For storage reasons I don't want to actually save the table from the first script, I just want to get the result from the first script and immediately apply the second script to it.
This is very basic, so any guidance would help.
The relevant term is known as a derived table.
In SQL you can use the result of a query as the input to another. The "nested query" produces the derived table which is then consumed by the outer query:
Select <columns>
from (
select <columns> from table join table etc
)as TableAliasName
To get the nomenclature right, what you have are not scripts or tables, but rather two queries. When a query runs it produces a result set.
To accomplish your goal, either of these queries will work:
SELECT
ApplicationId,
STRING_AGG(YEARLYPAYAMOUNT) allPremium,
STRING_AGG(SECTIONID) allSection,
STRING_AGG(SHORTNAME) allSectionName,
FROM (
SELECT *
FROM PROD_ANALYTIC.SRC_MVC_AU_DBO.BCAPPLICATIONQUOTES bq
JOIN PROD_ANALYTIC.SRC_MVC_AU_DBO.PRODUCT p ON bq.ProductId = p.Id
JOIN PROD_ANALYTIC.SRC_MVC_AU_DBO.BCAPPLICATIONQUOTEFEES F ON F.ApplicationQuoteId = bq.Id
LEFT JOIN PROD_ANALYTIC.SRC_MVC_AU_DBO.COVERAGESECTIONTYPE CST ON F.CoverageSectionTypeID = CST.SECTIONID
) appQuote
GROUP BY
ApplicationId
Here, the inner nested query is formally called a derived table, but people will often use the phrase "subquery".
The other option is a Common Table Expression (CTE):
With appQuote As (
SELECT *
FROM PROD_ANALYTIC.SRC_MVC_AU_DBO.BCAPPLICATIONQUOTES bq
JOIN PROD_ANALYTIC.SRC_MVC_AU_DBO.PRODUCT p ON bq.ProductId = p.Id
JOIN PROD_ANALYTIC.SRC_MVC_AU_DBO.BCAPPLICATIONQUOTEFEES F ON F.ApplicationQuoteId = bq.Id
LEFT JOIN PROD_ANALYTIC.SRC_MVC_AU_DBO.COVERAGESECTIONTYPE CST ON F.CoverageSectionTypeID = CST.SECTIONID
)
SELECT
ApplicationId,
STRING_AGG(YEARLYPAYAMOUNT) allPremium,
STRING_AGG(SECTIONID) allSection,
STRING_AGG(SHORTNAME) allSectionName,
FROM
appQuote
GROUP BY
ApplicationId
Finally, you could also create a View from the first query:
CREATE View AppQuote As
SELECT *
FROM PROD_ANALYTIC.SRC_MVC_AU_DBO.BCAPPLICATIONQUOTES bq
JOIN PROD_ANALYTIC.SRC_MVC_AU_DBO.PRODUCT p ON bq.ProductId = p.Id
JOIN PROD_ANALYTIC.SRC_MVC_AU_DBO.BCAPPLICATIONQUOTEFEES F ON F.ApplicationQuoteId = bq.Id
LEFT JOIN PROD_ANALYTIC.SRC_MVC_AU_DBO.COVERAGESECTIONTYPE CST ON F.CoverageSectionTypeID = CST.SECTIONID
A view is not just a query; it will actually become part of the database, such that you can use it in many of the same ways you would use a table saved on disk, and then the second query in the original question will run unmodified.
I am trying to write a SQL Select statement to port some data from a Sybase environment to a MongoDB environment and I'm just trying to figure out the correct syntax to involve three different tables.
Basically what I need to do is do an INNER JOIN on two tables, and then do a matching check against a 3rd table. The three table names are "ar_notes", "customer_service_xref" and "service_notes_details"
This is what I tried:
SELECT * FROM ar_notes arn
LEFT JOIN customer_service_xref csx ON arn.customer_service_xref_id = csx.id_number
WHERE arn.visit_date = service_notes_details.date_of_visit
This doesn't work. I get a correlation error.
What should the syntax look like when involving three tables like this?
You said you need an INNER JOIN among three tables but your query does a LEFT JOIN between two and tries another join in the WHERE clause without refering that table in the FROM clause.
To just fix your query:
SELECT *
FROM service_notes_details snd, ar_notes arn
INNER JOIN customer_service_xref csx ON arn.customer_service_xref_id = csx.id_number
WHERE arn.visit_date = snd.date_of_visit
This is what you should use in current SQL syntax:
SELECT *
FROM ar_notes arn
INNER JOIN customer_service_xref csx ON arn.customer_service_xref_id = csx.id_number
INNER JOIN service_notes_details ON arn.visit_date = service_notes_details.date_of_visit
To be clear, this will only return lines in ar_notes that have corresponding values in customer_service_xref (joining by customer_service_xref_id) and in service_notes_details(joining by visit_date). Your original query, using LEFT JOIN would return lines from ar_notes even if there was no matching customer_service_xref_id.
I have 3 tables:
1 - tblMembers_Info
2 - a junction table
3 - tblCourses
I need to query the members who haven't done a specific course.
After trying to do it manually I gave MS Access "Query Wizard" a try. I ended up with :
A saved query as Query1:
// That one query who did the course
SELECT tblMembers_Info.*, tblCourses.CourseName
FROM tblMembers_Info
INNER JOIN
(tblCourses INNER JOIN tblMembers_Courses
ON tblCourses.IDCourses = tblMembers_Courses.IDCourses)
ON tblMembers_Info.Members_ID = tblMembers_Courses.Members_ID
WHERE (tblCourses.CourseName) In ('NameOftheCourse');
2nd query using the saved Query1:
SELECT tblMembers_Info.Members_ID, tblMembers_Info.FirstName, tblMembers_Info.LastName
FROM tblMembers_Info
LEFT JOIN [Query1]
ON tblMembers_Info.[Members_ID] = Query1.[Members_ID]
WHERE (((Query1.Members_ID) Is Null));
How can I replace the Query1 in the second query with the full query instead of using a QueryDef (the saved query "Query1")?
Also, there's a better way for sure to write that query, I would really appreciate any help.
You can simply replace LEFT JOIN [Query1] with LEFT JOIN (...) AS [Query1] where ... should be the SQL of the first query, without the ending ;.
But I think in your specific case the use of NOT IN might give a better performance to get the same results:
SELECT tblMembers_Info.Members_ID, tblMembers_Info.FirstName, tblMembers_Info.LastName
FROM tblMembers_Info
WHERE tblMembers_Info.[Members_ID] NOT IN (
SELECT tblMembers_Info.[Members_ID]
FROM ((tblMembers_Info
INNER JOIN tblMembers_Courses
ON tblMembers_Info.Members_ID = tblMembers_Courses.Members_ID)
INNER JOIN tblCourses
ON tblCourses.IDCourses = tblMembers_Courses.IDCourses)
WHERE tblCourses.CourseName = 'NameOftheCourse'
);
I'm new to SQL and I'm currently writing a query and I got this error. Any help will be appreciated.
ORA-00933: SQL command not properly ended
My Query below:
CREATE VIEW moscow_paris_overlap(SSN) AS
SELECT t1.SSN
FROM assign AS T1
INNER JOIN assign AS T2
ON T1.SSN = T2.SSN
WHERE T1.EndYear = T2.StartYear
AND T1.CityName = 'Moscow'
AND T2.CityName = 'Paris';
SELECT DISTINCT emp.* FROM emp INNER JOIN moscow_paris_overlap ON emp.SSN = moscow_paris_overlap.SSN;
First, you need to separate the CREATE VIEW from the query which uses it. If you're using SQL*Plus or something similar you can do this by putting a / on a separate line between the two. This will cause the CREATE VIEW to be executed first.
Second, AS can't be used in a FROM or INNER JOIN when defining a table alias. Change the FROM clause in your view creation to FROM ASSIGN T1. Similarly, the INNER JOIN should be INNER JOIN ASSIGN T2.
I've got 5 tables. The main tables are: RisCtx, RisObj, and Ris.
RisCtx *-----------* RisObj
RisObj *-----------* Ris
(*---* = many-to-many)
So I got 2 more tables called: RisCtxRisObj and RisObjRis (for the many-to-many).
What I want is to create a view that collects all records from RisCtx which have a connection to Ris trough RisObj.
I've got kinda no clue :(.. I read something about INNER JOINs but I don't see a bit clearance...
The schema
CREATE VIEW `mydb`.`CtxView_CtxFromObj_ObjFromRisk` AS
select RisCtx.*
from RisCtx
inner join RisCtxRisObj on RisCtx.id=RisObjRisCtx.RisCtx_id
inner join RisObj on RisObjRisCtx.RisObj_id=RisObj.id
inner join RisObjRis on RisObj.id=RisObjRis.Objective_id
inner join Ris on RisObjRis.Risk_id=Ris.id
Since you haven't provided a schema, I can't show you what your ON clauses should look like, but the basic query structure is:
select RisCtx.*
from RisCtx
inner join RisCtxRisObj on ...
inner join RisObj on ...
inner join RisObjRis on ...
inner join Ris on ...