Sql Query over 3 tables with 2 many-to-many relations - sql

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 ...

Related

Problem with creating view with multiple joins Postgres

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?

Bundle 2 tables in 1 Inner Join

I have the sql code below. It works but when I run the query, it repeats the data more than one time. I believe it has something to do with the Inner Join. Since it is Inner Joining twice the data is repeating twice in the report. Any help is appreciated
SELECT NewRelative.FullName, GiftGave.EventName, GiftGave.EventDate, GiftGave.AmountGiven, GiftGave.Notes, GiftRcvd.EventName
FROM (NewRelative INNER JOIN GiftGave ON NewRelative.FullName = GiftGave.FullName) INNER JOIN GiftRcvd ON NewRelative.FullName = GiftRcvd.FullName
WHERE (((NewRelative.FullName)=[forms]![FormRelativeReport]![TxtPickRelative]));

Joining Two Queries onto a Shared Table

I have been struggling with the concept of combining results of two queries together via a join on a common table and I was hoping I could gain some assistance. The following is a rough guide to the tables:
dbo.Asset (not returned in the SELECT statement, used for joins only)
- dbo.Asset.AssetID
- dbo.Asset.CatalogueID
dbo.WorkOrder
- WorkOrderID
- AssetID
- WorkOrderNumber
dbo.WorkOrderSpare
- WorkOrderID
- WorkOrderSpareID
- WorkOrderSpareDescription
- ActualQuantity
- CreatedDateTime
dbo.Catalogue
- CatalogueID (PK)
- CatalogueNumber
- CatalogueDescription
- CatalogueGroupID
dbo.CatalogueGroup
- CatalogueGroupID
- CatalogueGroupNumber
First Query:
SELECT CatalogueGroup.CatalogueGroupName,
Catalogue.CatalogueNumber,
Catalogue.CatalogueDescription,
Catalogue.CatalogueID,
Asset.IsActive
FROM CatalogueGroup
INNER JOIN Catalogue
ON CatalogueGroup.CatalogueGroupID = Catalogue.CatalogueGroupID
INNER JOIN Asset
ON Catalogue.CatalogueID = Asset.CatalogueID
Second Query:
SELECT WorkOrder.WorkOrderNumber,
WorkOrderSpare.WorkOrderSpareDescription,
WorkOrderSpare.ActualQuantity,
WorkOrderSpare.CreatedDateTime
FROM WorkOrder
INNER JOIN WorkOrderSpare
ON WorkOrder.WorkOrderID = WorkOrderSpare.WorkOrderID
Now I can do the above easily enough in Access (WYSIWYG) by joining Asset/Catalogue/CatalogueGroup together and then joining Asset.AssetID onto WorkOrder.AssetID. I can't seem to get anything similar to work via raw code, I think I have my logic correct for the joins (INNER JOIN on the results of both) but then I am new to this.
Any assistance would be greatly appreciated, any pointers on where I can read further into problems like this would be great.
EDIT: This is what I was trying to use to no avail, I should also mention I am trying to do this in ms-sql, not Access (trying to move away from drag and drop):
SELECT CatalogueGroup.CatalogueGroupName,
Catalogue.CatalogueNumber,
Catalogue.CatalogueDescription,
Catalogue.CatalogueID,
Asset.IsActive,
WorkOrderSpare.WorkOrderSpareDescription,
WorkOrderSpare.ActualQuantity,
WorkOrderSpare.CreatedDateTime,
WorkOrder.WorkOrderNumber
FROM (((CatalogueGroup
INNER JOIN Catalogue
ON CatalogueGroup.CatalogueGroupID = Catalogue.CatalogueGroupID)
INNER JOIN Asset ON Catalogue.CatalogueID = Asset.CatalogueID)
INNER JOIN WorkOrderSpare
ON WorkOrder.WorkOrderID = WorkOrderSpare.WorkOrderID)
INNER JOIN WorkOrder ON Asset.AssetID = WorkOrder.AssetID
Think I see the issue. Assuming that the joins themselves are correct (ie your columns do relate to each other), the order of your joins is a little off - when you join WorkOrder to WorkOrderSpare, neither of those two tables relate back to any table you've identified up until that point in the query. Think of it as joining two tables separately from the chain of joins you have going so far - it's almost like doing two separate join queries. If you switch the last two it should work, that way WorkOrder will join to Asset (which you've already defined) and then you can join WorkOrderSpare to WorkOrder. I've also taken the liberty of removing parentheses on the joins, that's an Access thing.
SELECT CatalogueGroup.CatalogueGroupName,
Catalogue.CatalogueNumber,
Catalogue.CatalogueDescription,
Catalogue.CatalogueID,
Asset.IsActive,
WorkOrderSpare.WorkOrderSpareDescription,
WorkOrderSpare.ActualQuantity,
WorkOrderSpare.CreatedDateTime,
WorkOrder.WorkOrderNumber
FROM CatalogueGroup
INNER JOIN Catalogue ON CatalogueGroup.CatalogueGroupID = Catalogue.CatalogueGroupID
INNER JOIN Asset ON Catalogue.CatalogueID = Asset.CatalogueID
INNER JOIN WorkOrder ON Asset.AssetID = WorkOrder.AssetID
INNER JOIN WorkOrderSpare ON WorkOrder.WorkOrderID = WorkOrderSpare.WorkOrderID
I think you were close. As a slightly different approach to joining, try this:
SELECT CatalogueGroup.CatalogueGroupName,
Catalogue.CatalogueNumber,
Catalogue.CatalogueDescription,
Catalogue.CatalogueID,
Asset.IsActive,
WorkOrderSpare.WorkOrderSpareDescription,
WorkOrderSpare.ActualQuantity,
WorkOrderSpare.CreatedDateTime,
WorkOrder.WorkOrderNumber
FROM
CatalogueGroup, Catalogue, Asset, WorkOrder, WorkOrderSpare
WHERE CatalogueGroup.CatalogueGroupID = Catalogue.CatalogueGroupID
and Catalogue.CatalogueID = Asset.CatalogueID
and Asset.AssetID = WorkOrder.AssetID
and WorkOrder.WorkOrderID = WorkOrderSpare.WorkOrderID
It looks like it should work, but not having data, hard to know if simple joins all the way through is what you want. (It's a matter of personal preference whether to use the and clauses rather than the inner join syntax. While on style preferences, I like table aliases if supported, so FROM CatalogueGroup cg for example, so that you can refer to cg.CatalogueGroupID etc, rather than writing out the full table name every time.)
Ok. so the error that you noted in a comment
The multi-part identifier "WorkOrder.WorkOrderID" could not be bound
is usually when you have an alias for a table and instead of using alias in JOIN you use the table name or when you are using the wrong column name or table name.
Ideally in SQL server your query should look like this
SELECT
cg.CatalogueGroupName,
c.CatalogueNumber,
c.CatalogueDescription,
c.CatalogueID,
A.IsActive,
Wo.WorkOrderNumber,
WoS.WorkOrderSpareDescription,
WoS.ActualQuantity,
WoS.CreatedDateTime
FROM CatalogueGroup cg
INNER JOIN Catalogue c ON cg.CatalogueGroupID = c.CatalogueGroupID
INNER JOIN Asset A ON c.CatalogueID = A.CatalogueID
INNER JOIN WorkOrder Wo ON Wo.AssetID= A.AssetID
INNER JOIN WorkOrderSpare WoS ON Wo.WorkOrderID = WoS.WorkOrderID

SQLITE query, return records from multiple tables each joining their own metatable

I am developing a new database backend for my application for more flexibility.
Instead of one large table with many columns, I now have four tables;
Table "roms" (contains a single column 'Name')
Table "romsmeta" (contains columns 'Name','Title','Year')
Table "software" (contains columns 'System' and 'Name')
Table "softwaremeta" (contains columns 'System','Name','Title','Year')
So now I need to use a JOIN type in my queries, but my skills are a bit rusty. Basically, I would like to perform the following pseudo-query;
SELECT Title,Year from (roms INNER JOIN romsmeta,software INNER join softwaremeta) WHERE Title like '%enteredTitle%'
Obviously, this syntax is not valid.
What query would return the results I'm looking for?
Thanks in advance!
Try this:
SELECT rm.Title, rm.Year
from roms r
inner join romsmeta rm
on r.name = rm.name
inner join software s
on s.name = rm.name
inner join softwaremeta sm
on sm.name = rm.name
WHERE rm.Title like '%enteredTitle%'

SQL How to get columns from other tables based on other columns

I need to get values like
AdviserInit, AdviserSurname, MaterialName and Area using AdviserID, MaterialID and AreaCode from Chores Table as my reference.
I don't know what will be my approach in creating the query. This is what I've come up with so far:
SELECT Chores.ChoresID, Chores.ChoresDate, Materials.MaterialName,
Advisers.AdviserInit, Advisers.AdviserSurname, Area.Area,
Chores.StudentID
FROM Chores INNER JOIN Materials on Chores.MaterialID = Materials.MaterialID
INNER JOIN Advisers on Chores.AdviserID = Advisers.AdviserID
INNER JOIN Area on Chores.AreaCode = Area.AreaCode
Here's the screenshot of the relationships between the tables:
You can try this query, if you want to map all tables with main Chores Table,
SELECT Chores.ChoresID, Chores.ChoresDate, Materials.MaterialName,
Advisers.AdviserInit,Advisers.AdviserSurname, Area.Area,
Chores.StudentNo, Student.Forename
FROM (((Chores INNER JOIN Materials on Chores.MaterialID = Materials.MaterialID)
INNER JOIN Advisers on Chores.AdviserID = Advisers.AdviserID)
INNER JOIN Area on Chores.AreaCode = Area.AreaCode)
INNER JOIN Student on Student.StudentNo = Chores.StudentNo
The placement of the parentheses is important here. Basically, you need to have n - 2 left parentheses after the from clause and one right parenthesis before the start of each new join clause except for the first, where n is the number of tables being joined together.
The reason is that Access's join syntax supports joining only two tables at a time, so if you need to join more than two you need to enclose the extra ones in parentheses.