Group feedback by category and limit between date range - sql

Feedback belongs to Category and has scope :between, ->(start_date, end_date) { where(created_at: start_date.beginning_of_day..end_date.end_of_day) }
Question is, how do we get the count of feedbacks grouped by category and scoped to a certain date range to get something like:
1.5.2013 - 31.5.2013
Good 3
Bad 10
etc.
I got so far: Category.group(:name).joins(:feedbacks).count, but I'm stuck on how to plug the between date condition there.

Feedback.between(sd,ed).joins(:category).group("categories.name").count
# => {"Good" => 3, "Bad" => 1}

Related

Select documents from Fauna collection between two dates AND that satisfy another criteria

I am able to use the following code to retrieve documents from a Fauna collection that have a date which falls between start and end dates:
Paginate(Range(Match(Index("orders_by_date")) , start, end))
Is it possible to add another criteria to this statement to retrieve not only, in this case, orders between two dates but also have the field status = "completed".
Thank you
You can create an index that way:
CreateIndex(
{
name:'orders_by_date_status',
source:Collection("orders"),
terms: [{field:['data','status']}],
values:[{field:['data','order_date']},{field:['ref']}]
}
)
and query your collection with a query like this:
Paginate(
Range(
Match('orders_by_date_status','completed'),
[Date("2020-03-20")],
[Date("2020-06-20")]
)
)
to get back something like this:
{
data: [
[Date("2020-05-20"), Ref(Collection("orders"), "285246145700037121")],
[Date("2020-06-20"), Ref(Collection("orders"), "285246152717107713")]
]
}
Hope this answers your question.
Luigi

How to order by largest amount of identical entries with Rails?

I have a survey where users can post answers and since the answers are being saved in the db as a foreign key for each question, I'd like to know which answer got the highest rating.
So if the DB looks somewhat like this:
answer_id
1
1
2
how can I find that the answer with an id of 1 was selected more times than the one with an id of 2 ?
EDIT
So far I've done this:
#question = AnswerContainer.where(user_id: params[:user_id]) which lists the things a given user has voted for, but, obviously, that's not what I need.
you could try:
YourModel.group(:answer_id).count
for your example return something like: {1 => 2, 2 => 1}
You can do group by and then sort
Select answer_id, count(*) as maxsel
From poll
Group by answer_id
Order by maxsel desc
As stated in rails documentation (http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html) when you use group with count, active record "returns a Hash whose keys represent the aggregated column, and the values are the respective amounts"
Person.group(:city).count
# => { 'Rome' => 5, 'Paris' => 3 }

Active Record query to match every subset element

In my RoR application, I've got a database lookup similar to this one:
Client.joins(:products).where({'product.id' => [1,2,3]})
Unfortunately this will return all clients that have bought product 1, 2 or 3 but I only want to get back the clients, that bought all of the three products. In other words, I'd like to write a query that matches for n elements in a given set.
Are there any elegant solutions for this?
This is not really elegant. But it should translate into the needed SQL.
Client.joins(:products).
where({'products.id' => [1,2,3]}).
group('users.id').
having('COUNT(DISTINCT products.id) >= 3')
Same answer with more dynamic way
ids = [1,2,3]
Client.joins(:products).
where({'products.id' => ids}).
group('users.id').
having('COUNT(DISTINCT products.id) >= ?', ids.size)

How can I retrieve the newest record in each group in a DBIx::Class resultset search?

I'm using group_by in a DBIx::Class resultset search. The result returned for each group is always the row in the group with the lowest id (i.e the oldest row in the group). I'm looking for a way to get the row with the highest id (i.e. the newest row in the group) instead.
The problem is fundamentally the same as this:
Retrieving the last record in each group
...except that I'm using DBIx::Class not raw SQL.
To put the question in context:
I have a table of music reviews
review
------
id
artist_id
album_id
pub_date
...other_columns...
There can be multiple reviews for any given artist_id/album_id.
I want the most recent reviews, in descending date order, with no more than one review per artist_id/album_id.
I tried to do this using:
$schema->resultset('Review')->search(
undef,
{
group_by => [ qw/ artist_id album_id / ],
order_by => { -desc => 'pub_date' },
}
);
This nearly works, but returns the oldest review in each group instead of the newest.
How can I get the newest?
For this to work you are relying on broken database behaviour. You should not be able to select columns from a table when you use group by unless they use an aggregate function (min, max etc.) or are specified in the group by clause.
In MySQL, even the manual admits this is wrong - though it supports it.
What I think you need to do is get the latest dates of the reviews, with max(pub_date):
my $dates = $schema->resultset('Review')->search({},
{
select => ['artist_id', 'album_id', {max => 'pub_date'}],
as => [ qw(artist_id album_id recent_pub_date) ],
group_by => [ qw(artist_id album_id) ],
}
);
Then loop through to get the review:
while (my $review_date = $dates->next) {
my $review = $schema->resultset('Review')->search({
artist_id => $review_date->artist_id,
album_id => $review_date->album_id,
pub_date => $review_date->get_column('recent_pub_date'),
})->first;
}
Yep - it's more queries but it makes sense - what if two reviews are on the same date - how should the DB know which one to return in the select statement?

How to define new instantaneous variable row by row - RAILS3 BEGINNER

I was hoping somebody may be able to point me in the right direction...
I have a database called Info and use a find command to select the rows in this database which match a certain criteria
#matching = Info.find( :all, :conditions => ["product_name = ?", distinctproduct], :order => 'Price ASC')
I then pull out the cheapest of these items
#cheapest = #matching.first
Finally, I would like to create an instantaneous array which contains a list of #cheapest for a number of different search criteria. i.e. row 1 in #allcheapest is #cheapest for criteria 1, row 2 in #allcheapest is #cheapest for criteria 2, ...
Any help would be great, thanks in advance
Info.where(:product_name => distinct_product.to_s).order('Price ASC').first
to select the cheapest price for the product_name. Without more insight into how your database is structured, it is difficult to suggest how to obtain the latter, but you may try
Info.where(:product_name => distinct_product.to_s).order('Price ASC').group(:product_name)