Select query, join table which is not directly referenced via Foreign Key - sql

With Prisma, I'm trying to join an indirectly referenced table onto a query, see SQL example below which represents the basic use case.
Lets say in the example, that I want to access the companyCar table from the companyUser table. I can think of 2 ways to do this, via joining using the company table, or by directly comparing the companyId of the 2 tables
option 1, follows foreign key references
SELECT * FROM CompanyUser companyuser
JOIN Company company on company.Id = companyuser.companyId
JOIN CompanyCar companycar on companycar.companyId = company.Id
option 2, does not directly follow foreign key references
SELECT * FROM companyUser companyuser
JOIN CompanyCar companycar on companycar.companyId = companyuser.companyId
How do I solve this within the prisma framework using includes or some other mechanism?

I recieved a response from one of the devs on github. See the link below stating that currently a rawQuery must be used, but this feature is an outstanding feature request.
https://github.com/prisma/prisma/discussions/14905

Related

How do I write a query to display the customer who claimed maximum amount from an ERD diagram?

This is what I wrote but I am not getting the correct answer:
select top 1 customer.first_name
from customer, claims
where customer.id = claims.id
order by claims.amount_of_claim desc
GO
You are joining claim.id and customer.id. Those will never match except by accident. The number on a claims document will never match the number on your insurance card or policy except by accident.
When you write a query, the table rows are matched based only on the query expressions, not any constraints between tables. This means that the following query will try to match unrelated things:
select top 1 customer.first_name
from customer inner join claims
on customer.id = claims.id
order by claims.amount_of_claim desc
The diagram shows that a Claim is related to a Policy which in turn is related to a customer:
Claims(customer_policy_id) -> Customer_Policy(customer_id) -> Customer
You'll have to join these 3 tables in your query
select top 1 cust.first_name
from customer cust
inner join customer_policy pol on cust.id=pol.customer_id
inner join claims cl on pol.id=cl.customer_policy_id
order by cl.amount_of_claim desc
In a relational database relations are represented by tables, not foreign key constraints. A Foreign Key Constraint is used to ensure that the FK values stored in a table are valid.
On top of that, an ER diagram is not a database diagram. The entities and relations shown in an ER diagram are don't map directly to tables. For example, a many-to-many relation between eg Customer and Address in an ER diagram would have to be translated to a bridge table, CustomerAddresses(CustomerId,AddressId). After all, a table is a relation in relational theory, and CustomerAddresses defines the relation between Customer and Address.

How to compare attributes from tables that are 3 relationships apart in SQL

I need to produce some sample SQL for a database to be created with an ERD that I have already made.
The required query is https://imgur.com/vDvL1ZS
and the ERD being used is https://imgur.com/a/hzTQhPU
I've assumed that I need to select from the 3 tables (Message, Chat, UserChat) but I don't understand how the query would be able to match up each instance of messages and users. I've tried to make somewhat of a starting point below but can't see what else would be required.
SELECT MessageID, ChatID, IsText, MessageText, FileName, MessageFile
FROM tbl_Message, tbl_Chat, tbl_UserChat
WHERE tbl_Message.DateSent > UserChat.LastOpened
AND tbl_User.UserID = ‘1044’
AND tbl_Chat.ChatID = ‘139’
A primary key is a field or set of fields which are unique across your table. Each row has its unique primary key.
A foreign key is a field or set of fields, containing only values that are another's table primary key. It is basically a reference to another table.
You can link tables that have references to each others using joins. Here, you are trying to link the Message, Chat and UserChat tables, like so:
select
*
from
UserChat
join
Chat on UserChat.ChatID = Chat.ChatID
join
Message on Chat.ChatID = Message.ChatID
As you can see, I "chained" the joins as the relationships are in the diagram.
Now we got our tables linked, we can add our filters, and only select the Message fields:
select
Message.*
from
UserChat
join
Chat on UserChat.ChatID = Chat.ChatID
join
Message on Chat.ChatID = Message.ChatID
where
UserChat.ChatID = y -- Filter the correct chat
and
UserChat.MessageID = x -- Filter the correct user
and
UserChat.LastOpened < Message.DateSent -- Filter only unread messages

SQL JOIN from other JOIN

So, this is probably gonna sound like a weird or dumb question.
I have this application that I'm writing, which consists of four tables. Two are 'connected' to one main table, and one last one is connected to one of those two tables. I've included a database diagram to give you a better idea of what I mean.
Now, my goal is to have 'Bedrijfsnaam' from the 'Bedrijven' table into the 'Samenwerkingen' table. Problem is: I can't add more than two foreign keys, so I was assuming that I would have to create a FK in'Contactpersonen' table and pick it from the 'Bedrijven' table. It would basically mean I'd have a JOIN in 'Contactpersonen' table to my 'Bedrijven' table. And then the 'Samenwerkingen' table has a JOIN to the 'Contactpersonen' table and accesses the column from 'Bedrijven'.
Does that make any sense? Hope it does, because I could really use some help making this possible. xD
Since Samenwerkingen has a foreign key to Contactpersonen which is itself related to Bedrijven, you don't need an additional constraint: your data integrity is guaranteed and you can join the two tables.
Your query should look like :
select s.*, b.* from Samenwerkingen s
inner join Contactpersonen c on s.Contactpersonen = c.Contactpersonen
inner join Bedrijven b on c.Bedrijfnaam = b.Bedrijfnaam

Access: Updatable join query with 2 primary key fields that are both also foreign keys

In MS Access, I am trying to implement a many-to-many table that will store 2-way relationships, similar to Association between two entries in SQL table. This table stores info such as "Person A and Person B are coworkers" "C and D are friends", etc. The table is like this:
ConstitRelationships
LeftId (number, primary key, foreign key to Constituents.ConstitId)
RightId (number, primary key, foreign key to Constituents.ConstitId)
Description (text)
Note that the primary key is a composite of the two Id fields.
Also the table has constraints:
[LeftId]<>[RightId] AND [LeftId]<[RightId]
The table is working ok in my Access project, except that I cannot figure out how to make an updateable query that I want to use as a datasheet subform so users can easily add/delete records and change the descriptions. I currently have a non-updatable query:
SELECT Constituents.ConstituentId, Constituents.FirstName,
Constituents.MiddleName, Constituents.LastName,
ConstitRelationships.Description, ConstitRelationships.LeftId,
ConstitRelationships.RightId
FROM ConstitRelationships INNER JOIN Constituents ON
(Constituents.ConstituentId =
ConstitRelationships.RightId) OR (Constituents.ConstituentId =
ConstitRelationships.LeftId);
If I ignore the possibility that the constituentId I want is in the leftId column, I can do this, which is updatable. So the OR condition in the inner join above is what's messing it up.
SELECT Constituents.ConstituentId, Constituents.FirstName,
Constituents.MiddleName, Constituents.LastName,
ConstitRelationships.Description, ConstitRelationships.LeftId,
ConstitRelationships.RightId
FROM ConstitRelationships INNER JOIN Constituents ON
(Constituents.ConstituentId =
ConstitRelationships.RightId) ;
I also tried this wacky iif thing to collapse the two LeftId and RightId fields into FriendId, but it was not updateable either.
SELECT Constituents.ConstituentId, Constituents.FirstName,
Constituents.MiddleName,
Constituents.LastName, subQ.Description
FROM Constituents
INNER JOIN (
SELECT Description, Iif([Forms]![Constituents Form]![ConstituentId] <>
ConstitRelationships.LeftId, ConstitRelationships.LeftId,
ConstitRelationships.RightId) AS FriendId
FROM ConstitRelationships
WHERE ([Forms]![Constituents Form]![ConstituentId] =
ConstitRelationships.RightId)
OR ([Forms]![Constituents Form]![ConstituentId] =
ConstitRelationships.LeftId)
) subQ
ON (subQ.FriendId = Constituents.ConstituentId)
;
How can I make an updatable query on ConstitRelationships, including a JOIN with the Constituent.FirstName MiddleName LastName fields?
I am afraid that is not possible. Because you use joins in your query over three tables it is not updatable. There is no way around this.
Here some detailed information about the topic: http://www.fmsinc.com/Microsoftaccess/query/non-updateable/index.html
As mentioned in the linked article one possible solution and in my opinion best solution for you would be the temporary table. It is a load of work compared to the easy "bind-form-to-a-query"-approach but it works best.
The alternative would be to alter your datascheme in that way that you do not need joins. But then denormalized data and duplicates would go rampage which makes the temporary table a favorable choice.

Inserting Into and Maintaining Many-to-Many Tables

SQLite3 user.
I have read thru numerous books on relational DBs and SQL and not one shows how to maintain the linking tables for many-to-many relationships. I just went through a book that went into the details of SELECT and JOINS with examples, but then glosses over the same when many-to-many relationships are covered. The author just showed some pseudo code for a table, no data, and then a pseudo code query--WTF? I am probably missing something, but it has become quite maddening.
Anyways, say I have a table like [People] with 3 columns: pID (primary), name and age. A table [Groups] with 3 columns: gID (primary), groupname and years. Since people can belong to multiple groups and groups can have multiple people, I set up a linking table called [peoplegroups] with two columns: pID, and gID both of which come from their respective tables.
So ,how do I efficiently get data into the linking table when INSERTING on the others and how do I get data out using the linking table?
Example: I want to INSERT "Jane" into [people] and make her a member of group gID 2, "bowlers" and update the linking table {peoplegroups] at the same time.
Later I want to go back and pull out a list of all of the bowlers or all the groups a person is part of.
If you already don't use primary and foreign keys (which you should!) I think you may need to consider using triggers in your design as well? So if you have a specific set of rules (e.g. if you want to create Jane with id = 1 and choose existing group 2, then after insert jane into people automatically create an entry pair personid=1,groupid=2 in the table peoplegroups. You can also create views with specific selects to see the data you want, for example if you want a query where you only show the peoples names and groups names you could create a view 'PeopleView':
SELECT P.PersonName, G.GroupName
FROM People P
INNER JOIN PeopleGroup PG ON P.PersonID = PG.PersonID
INNER JOIN Group G ON G.GroupId = PG.GroupID
then you can query 'PeopleView' saying
SELECT * FROM PeopleView WHERE GroupName = 'bowlers'
When inserting new data into the tables mentioned, the "linking" table that you are referring to needs to contain both primary keys from the other tables as foreign keys. So basically The [People] tables (pID) and the [Groups] table (gID) should both be foreign keys in the [PeopleGroups] table. In order to create a new "link" in [PeopleGroups] the record has to already exist in the [People] table as well as the [Groups] table BEFORE you try and create the link in the [PeopleGroups] table. I hope this helps