Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support JOINs in UpdateStatement (join_subquery, inner_join, etc.) #608

Open
LeoniePhiline opened this issue Feb 21, 2023 · 10 comments
Open

Comments

@LeoniePhiline
Copy link

LeoniePhiline commented Feb 21, 2023

Motivation

It is rather handy (and often required?) to gather related entities in an UPDATE statement, and update some fields based on joined tables.

For example, here each institution has several subscriptions (with subscriptions.institution being a foreign key to institutions.uid).

An append-only activity table records users of these institutions using the subscriptions.

Periodically, the institutions' and subscriptions' last_activity datetime field shall be updated.

Updating last_activity on subscriptions

UPDATE subscriptions AS entity
INNER JOIN (
    SELECT subscription.uid AS entity_uid, MAX(date_time) AS last_activity
    FROM activity
    INNER JOIN subscriptions AS  subscription ON subscription.uid = activity.subscription
    GROUP BY subscription.uid
) AS entity_activity
    ON entity_activity.entity_uid = entity.uid
SET entity.last_activity = entity_activity.last_activity;

Updating last_activity on institutions

UPDATE institutions AS entity
INNER JOIN (
    SELECT institution.uid AS entity_uid, MAX(date_time) AS last_activity
    FROM activity
    INNER JOIN subscriptions AS subscription ON subscription.uid = activity.subscription
    INNER JOIN institutions AS institution ON institution.uid = subscription.institution
    GROUP BY institution.uid
) AS entity_activity
    ON entity_activity.entity_uid = entity.uid
SET entity.last_activity = entity_activity.last_activity;

My wish here was to use (simplified):

let query = Query::update()
    .table(Subscriptions::Table)
    .join_subquery(
        JoinType::InnerJoin,
        ...
    )
    .value(...);

But joins are unavailable on UpdateStatement.

Proposed Solutions

Add methods available on SelectStatement to UpdateStatement:

  • join
  • join_as
  • join_lateral
  • join_subquery
  • inner_join
  • left_join
  • right_join
  • full_outer_join

Additional Information

I will try to work around this using CTEs (UpdateStatement::with). Edit: This workaround won't work in MariaDB: https://jira.mariadb.org/browse/MDEV-18511

This feature request for UPDATE TABLE ... JOIN ... SET ... is related to #627 - a feature request for DELETE ... FROM ... JOIN ....

@tyt2y3
Copy link
Member

tyt2y3 commented Feb 22, 2023

SeaQuery has support for UPDATE SELECT FROM and UPDATE SET=SUB_QUERY, so they might also do the same trick.

@LeoniePhiline
Copy link
Author

LeoniePhiline commented Feb 22, 2023

I'm afraid these aren't supported by MariaDB. But I might be missing something...

Update Syntax is documented here: https://mariadb.com/kb/en/update/

And table_references as mentioned at the above URL are documented here: https://mariadb.com/kb/en/join-syntax/

Is table_factor table_subquery (see documentation at second URL) the syntax you are referring to?

If UPDATE (SELECT FROM) was supported by MariaDB, how would I construct this query with an UpdateStatement?

@tyt2y3
Copy link
Member

tyt2y3 commented Feb 23, 2023

Sad, we only got INSERT SELECT FROM but not in update. Ref: https://docs.rs/sea-query/latest/sea_query/query/struct.InsertStatement.html#method.select_from

I think it can be added.

@LeoniePhiline
Copy link
Author

That would be greatly appreciated! =)

@AdamJSoftware
Copy link

Any news on this?

@the-wondersmith
Copy link

@AdamJSoftware I put up a PR that at least partially addresses it. Not sure how to get traction on getting it merged though 🤔

@the-wondersmith
Copy link

@tyt2y3 @LeoniePhiline any idea who to ping about the PR for this?

@LeoniePhiline
Copy link
Author

They'll have been notified already.

@the-wondersmith
Copy link

the-wondersmith commented Nov 19, 2024

@LeoniePhiline it's been ~3 weeks without so much as a comment on the open PR.

I hate to be a bother, but do you happen to know if there is a way I might be able to expedite movement on that front? Even a "hate everything about it, will not merge" would be better than radio silence at this point IMO 😅

@LeoniePhiline
Copy link
Author

You could ask on the discord server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants