Connecting Multiple Relationships with Many-To-Many Matches

My database consists of the following entities:

@Entity
class User {
    @ManyToMany(type => Group)
    @JoinTable()
    groups: Group[];
}

@Entity
class MediaObject {
    @ManyToMany(type => Group)
    @JoinTable()
    groups: Group[];
}

@Entity
class Group {
    // [...]
}

Now, I am looking to retrieve all MediaObjects that share at least one group with a specific User.

For instance, consider the following scenario:

User 1          MediaObject 1
-----------------------------
Group 1    |--- Group 2 
Group 2 ---|    Group 3

User 1 has at least one common group with MediaObject

How can I construct a SQL query to achieve this? I am utilizing Typeorm for my queries, so any SQL query or insight into how Typeorm performs table joins would be greatly appreciated.

LEFT JOIN "group" "groups" ON "groups"."id" = "media_groups"."groupId" 

Answer №1

To fetch the IDs of MediaObjects that have at least one group in common with the user, a simple JOIN can be used. After that, utilize IN to retrieve those MediaObject's.

select *
from MediaObject mo
where mo.id in
(
    select moJoin.mediaObjectId
    from media_object_groups_group moJoin
    join user_groups_group uJoin on moJoin.groupId = uJoin.groupId
    where uJoin.userId = 1
)

Answer №2

If there are multiple overlapping groups within the same MediaObject and for the same User, utilizing an EXISTS semi-join could potentially yield faster results compared to using IN:

SELECT m.*
FROM   "MediaObject" m
WHERE  EXISTS (
   SELECT -- the select list may be empty in this case
   FROM   user_groups_group         gu
   JOIN   media_object_groups_group gm USING ("groupId")
   WHERE  gu."userId" = 1
   AND    gm."mediaObjectId" = m.id
   );

Alternatively, you can also consider using Radim's query, which should work well with some added double-quotes.

This method assumes that referential integrity is maintained through foreign key constraints, making it safe to utilize user_groups_group."userId" without verifying the existence of the corresponding user.

It's advisable to avoid using reserved words like "user" or "group", as well as CaMeL-case strings as identifiers. In such cases, double-quoting is mandatory. ORMs often struggle in handling these scenarios effectively. Refer to:

  • Are PostgreSQL column names case-sensitive?

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The optimal time to register for events within the Vue lifecycle

Currently, I am developing a Vue2 component using vue-component that includes a subcomponent. Here is an example: <note :bus="bus" :itemId="selectedId"></note> The subcomponent contains the following code snippet: <textarea v-model="text" ...

I am interested in updating the content on the page seamlessly using Angular 6 without the need to reload

As a newcomer to Angular, I am interested in dynamically changing the page content or displaying a new component with fresh information. My website currently features cards, which you can view by following this Cards link. I would like to update the page ...

Encountered an issue while attempting to integrate Nebular into my Angular application

As a newcomer to Angular, I decided to try installing Nebular using the command ng add @nebular/theme. However, I encountered an error in the process. Upon entering the command into my terminal, the following error message appeared: ? Which Nebular theme ...

The React namespace is missing the exported member 'InputHTMLAttributes', and the MenuItemProps interface is incorrectly extending the ListItemProps interface

I am currently working with Material-UI and typescript. I have installed the typescript types using npm install -D @types/material-ui. After loading my webpage, I encountered the following errors: ERROR in [at-loader] ./node_modules/@types/material ...

PostgreSQL logic/query for tracking user preferences

I am new to postgreSQL and looking for a way to increase or decrease a field by 1, similar to how you can do with firestore using FieldValue.increment(1). Situation: Consider a scenario where a post (a column in a table) has a value of 10 and 5 users atte ...

Enhancing Web Service Calls with Angular 2 - The Power of Chaining

I am currently facing an issue where I need to make multiple web service calls in a sequence, but the problem is that the second call is being made before the .subscribe function of the first call executes. This is causing delays in setting the value of th ...

Utilize a list of Data Transfer Objects to populate a dynamic bar chart in recharts with

I received a BillingSummaryDTO object from a Rest API using Typescript: export interface BillingSummaryDTO { paid?: number, outstanding?: number, pastDue?: number, cancelled?: number, createdAt?: Moment | null, } export async function ...

The Angular Ivy strictTemplates error message states that the type 'Event' cannot be assigned to the type 'InputEvent' parameter

I'm feeling lost trying to figure out what's wrong with this code snippet: <input #quantity type="number" matInput formControlName="quantity" (input)="onQuantity($event, i)" placeholder="Quantity"/> onQuantity(event: InputEvent, i: number ...

"Utilize React and Redux to fetch data from the server after making changes with an API

I am currently using a combination of react, redux, and typescript in my project. My goal is to add an item from the react component by making an API call and then displaying whether the operation was successful or not. To achieve this, I am fetching data ...

combining duplicate values using group_concat and join operations

I'm struggling with a query that is returning multiple values and I need some help. Here is the output that I am currently getting: +----+--------------+--------+--------+---------------------+----------+------------------+ | id | company | cou ...

Angular does not update the progress bar

Imagine having a component html with your own customized round progress bar <round-progress #progress [current]="current" </round-progress> The "Current" value represents the percentage. In my TypeScript component, I have written: ...

Send information as FormData object

I'm getting the data in this format: pert_submit: {systemId: "53183", pert-id: "176061", score: 0, q2c: "3\0", q2t: "", …} Now I need to send it as FormData in my post request. Since I can't use an ...

Here is a guide on showcasing information obtained from ASP.NET API in Angular version 13

My goal is to fetch motorcycle data from a web API and showcase it in my Angular project. ASP.NET Framework Web API 4.7 Angular CLI: 13.3.7 Angular: 13.3.11 On the Web API end: Controller: [EnableCors(origins: "*", headers: "*", ...

Tips for managing the error message "The key 'myOptionalKey' is optional in the 'myObject' type but necessary in the '{...}' type"

Issue I'm currently working on making a sortable table using a sample table component from Material-UI. I encountered an error when I included an optional key in the Data object. It seems that the type definition in the getComparator function does no ...

Guide to importing a function from a Javascript module without declaration

Currently, I am utilizing a third-party Javascript library that includes Typescript type declarations in the form of .d.ts files. Unfortunately, as is often the case, these type declarations are inaccurate. Specifically, they lack a crucial function which ...

What are some effective strategies for optimizing the deletion of records from a table with millions of rows to increase efficiency?

BEGIN TRANSACTION BEGIN TRY ;WITH CTE_WORK_QUOTES AS ( SELECT WORKID, QUOTE_NO FROM TABLE_WORK_QUOTES WITH(INDEX(PRIMARY_KEY)) WHERE ID != '' ) DELETE WQ ...

Angular 4: Transform a string into an array containing multiple objects

Recently, I received an API response that looks like this: { "status": "success", "code": 0, "message": "version list", "payload" : "[{\"code\":\"AB\",\"short\":\"AB\",\"name\":\"Alberta&b ...

How can I display an agm-polyline within a map in Angular 7?

I need assistance with adjusting the polylines on my map and dynamically setting the zoom level based on their size and position. Here is the code I am currently using: <agm-map style="height: 500px" [latitude]='selectedLatitude' [longitude ...

Troubleshooting MySQL Concatenation and Trimming in a Select Query to Validate Existence in Another Table - Where is my code failing?

Table_Base +----+----------------+ | ID | ACCOUNT | +----+----------------+ | 1 | 100 | | 2 | 120 | | 3 | 193 | | 4 | 201 | | 5 | 213 | | 6 | 247 | | 7 | 304 | ...

What is the best way to implement an IN clause in iBATIS?

Currently utilizing iBATIS for crafting select statements. Seeking guidance on efficiently implementing the following SQL statement with iBATIS: SELECT * FROM table WHERE col1 IN ('value1', 'value2'); Encountering an issue where the s ...