-
-
Notifications
You must be signed in to change notification settings - Fork 568
Aggregate APIs #47
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
Comments
So, it allows user to aggregate by column(s) / expression on any of the supported aggregation method (i.e. sum, avg, max, min)? |
My idea was to have a struct called |
How about "Select A, SUM(B) AS B FROM Table GROUP BY A"? |
I think it should work similar to Paginator, creating a sub query is the safest |
So the result is just a simple type |
Oh, not yet thought of this. No, it can't be type T. We need to query the column type in runtime and select the appropriate Value variant |
Btw... we should consider changing the return type of e.g. Postgres prefer i64; MySQL is okay with both i32 & i64 |
I think the result of count is not dependent on the column type, only dependent on the database driver. Using i64 is the safest bet. |
Yes! |
So all these methods (
What you mean by selecting an appropriate |
Well, if the column itself is a Double, then the avg result would be f64. It could be decimal, i32 and so on. |
Yes, think so! Generic types loll |
To whom it may concern, if it is important to you, make a comment. |
I'm moving from |
Hey @BenJeau, thanks for the help! I have a rough idea in mind on how this could be done. It would be similar to sea-orm/src/executor/paginator.rs Lines 183 to 202 in a517e9d
Let say we create an
#[async_trait::async_trait]
pub trait AggregatorTrait
{
fn aggregate(self, db: &'db C) -> Aggregator;
}
pub struct Aggregator<'db, C>
where
C: ConnectionTrait,
{
pub(crate) query: SelectStatement,
pub(crate) db: &'db C,
}
impl<'db, C> Aggregator<'db, C> {
pub fn count<T>(col: T) -> Result<i64, DbErr>
where
T: ColumnTrait
{
todo!()
}
} So, the public API would be let count: i64 = cake::Entity::find()
.aggregate(db)
.count(cake::Column::Id)
.await?; And we could use subquery to select the aggregated result, it would be easier to for us to implement. SELECT COUNT(sub.id) FROM (SELECT cake.id, cake.name FROM cake) AS sub |
Is there still interest in this feature being implemented? |
I think so, it's marked as a good first issue anyway |
I'll give this issue a shot in the coming days. |
Is this issue still active @billy1624 ? |
If nobody minds, I would like to claim this task :) . |
@billy1624 Following your suggestion, it seems that you would like the count function to actually return the number of rows. Do I assume corrrectly that sea-orm currently does not provide a way to access counts for tables? |
Hey @LemarAb, we do have methods to construct aggregate expression in SeaORM. |
@billy1624 so there is no intention to make the APIs compatible with further querying, as we return i64 immediately, only (one) aggregation should be performed per Can you elaborate on your previous comment:
Why is there a necessity for a subquery ? |
Hey @LemarAb, I saw it the other way round. User can perform filtering or even pre-aggregating, then aggregate it to produce the final result. SELECT COUNT(sub.id)
FROM (SELECT cake.id, cake.name FROM cake WHERE ... GROUP BY ... HAVING ...) AS sub Ideally we wrap the original select statement in a subquery because this way we always perform aggregation on a query result of a black box. I imagine the API be like: let count: i64 = cake::Entity::find()
.count(cake::Column::Id) // method defined in `AggregatorTrait` to construct the `Aggregator` struct
.one(db) // method defined in `Aggregator` struct
.await?; |
Okay @billy1624 , we are on the same page when it comes to pre-filtering, but I am concerned with what comes after the Your proposal further above intended an i64 to return as a result of the count method...what methods should be callable after that? As far as I am aware, we can implement the call to the |
The let count: i64 = cake::Entity::find()
.count(cake::Column::Id) // 1) Convert into `Aggregator`
.some_more_fn(...) // 1.x) Leave room for future API addition
.one(db) // 2) Run the query
.await?; Does that make sense? |
Why not replace Ref :and_then |
@billy1624 so opposite to what you suggested further above, count should not return the number right away, but return |
For example we can implement |
|
Is this still open? I've been looking into this, but I'm having trouble figuring out a way to generalize the result over a set of numeric types. I'm currently doing this in the Aggregator:
I'm sure there is a better way of doing this based on the ColumnType of the ColumnTrait from the sum() parameter, but I can't figure it out. |
Add a new trait
AggregatorTrait
to be impl by Selector*count()
and
sum
avg
max
min
by specifying a column to aggregate onThe text was updated successfully, but these errors were encountered: