How can I count unique values in a table in Rails? - ruby-on-rails

I have a table "stock" which consists of many package_ids
package_id = 1
package_id = 3
package_id = 2
package_id = 3
package_id = 3
package_id = 4
package_id = 2
What is the most elegant way to:
count each unique package_id in the db, e.g.: package_id 1 = one time
in the db; package_id 2 = two times in the db; package_id 3 = three
times in the DB ...
echo the top 3 of package IDs afterwards
I have tried this step by step:
counting each single package_id (Stock.where(:package_id => 1).count)
putting that all in an array
and sort that array from high to low (only first 3 items)
This however does not seems to be an effective path though.

How about:
Stock.group(:package_id).count
It will return a hash having package_id as a key and the count as a value:
{ package_id1: count1, package_id2: count2 ....}

Try with this to get the 'Top 3':
Stock.select('package_id, count(*) as c').group(:package_id).order('c DESC').limit(3)

Related

Return only 5 unique random objects

Have a page that shows 1 restaurant and below is the list of 5 suggested restaurants = objects (random list of restaurants with various properties such as the name of the restaurant, cusineType, rating, location). Returning back 5 random objects.
var random = new Random(); var results = restaurants.Where(restaurant => restaurant.cusineType == "Sushi").OrderBy(x => random.Next()).Take(5).ToList();
With the current setup, it returns 5 random restaurants, but:
it can return in the list the same restaurant as the one loaded on the page
it can return 2 same objects in the list
How to make it return only unique 5 random objects?
you can use skip() and take() on the list and get a random entities.
var distributes = _home.GetDistributeCenter().ToList();
Random rand = new Random();
int toSkip = rand.Next(0, distributes.Count - 6);
var randomlist = distributes.Skip(toSkip).Take(5).ToList();

how to display name use LINQ

Actually i have two tables i want to display records of the use of second table. Please help me in this. Let me provide you example.
[TABLE1]
LocationID LoginID Location_Name
1 101 A
2 102 B
3 103 C
[TABLE2]
ID LoginID No_Of_Item Location ToLocation
1 101 5 1 2
2 102 6 2 3
3 103 7 1 3
This is my database. Now i want to show [TABLE2] records with location name. But i am unable to do that. Please help me in this LINQ Query.
This is my code.
public IQueryable<StockTransferViewModel> GetAllStockTransferDetailByLoginId(string LoginId)
{
var StockList = (from aspuser in context.AspNetUsers
join cus in context.Customers on aspuser.Id equals cus.LoginID
join transfer in context.StockTransfers on aspuser.Id equals transfer.LoginID
where transfer.LoginID == LoginId
select new StockTransferViewModel
{
ID = transfer.ID,
LoginID = transfer.LoginID,
Date_Of_Transfer = transfer.Date_Of_Transfer,
No_Of_Sku = transfer.No_Of_SKU,
FromLocationName=transfer.Location,
ToLocation=transfer.ToLocation,
}).AsQueryable();
return StockList;
}
If TABLE1 is named Locations, you'll likey want to add the following lines after the line starting with join transfer in:
join fromLocation in context.Locations on transfer.Location equals fromLocation.LocationID
join toLocation in context.Locations on transfer.Location equals toLocation.LocationID
Then in your select statement, you'll want:
FromLocationName = fromLocation.Location_Name,
ToLocation = toLocation.Location_Name,

How to get Average rating in entity framework

Hi I have below code as
var query = (from R in db.Registrations
join c in db.Campus
on R.CampusId equals c.CampusId
from tsr in db.TutorStudentRequests.Where(t => t.TutorId == R.RegistrationId).DefaultIfEmpty()
where R.UserTypeId == 2 && tsr.StatusId!=3
orderby R.Name ascending
select new
{
RegistrationId = R.RegistrationId,
Name = R.Name,
Email = R.Email,
Phone = R.Phone,
Password = c.CampusName,
IsGPA = R.IsGPA,
IsActive = R.IsActive,
StripeId = R.StripeId,
CreatedOn = R.CreatedOn,
UserTypeId =tsr.StudentReviewRating
})
.ToList();
I have Registration table having single row and I also have another table TutorStudentRequests which have multiple rows. How can I get average of column name StudentReviewRating present in TutorStudentRequests table?
Structure may be seem as:
Registration Table
RegistrationId Name Email
1 abc abc#gmail.com
2 xyz xyz#gmail.com
TutorStudentRequests Table
Id TutorId(RegistrationId of F.k.) StudentReviewRating
1 1 5
2 1 2
3 1 1
4 2 3
I want UserTypeId data as average of StudentReviewRating for each TutorId
Tried
var query = (from R in db.Registrations
join c in db.Campus
on R.CampusId equals c.CampusId
from tsr in db.TutorStudentRequests.Where(t => t.TutorId == R.RegistrationId).DefaultIfEmpty()
where R.UserTypeId == 2 && tsr.StatusId != 3
group R by new
{
R.RegistrationId,
R.Name,
R.Email,
R.Phone,
c.CampusName,
R.IsGPA,
R.IsActive,
R.StripeId,
R.CreatedOn,
} into groupings
select new
{
RegistrationId = groupings.Key.RegistrationId,
Name = groupings.Key.Name,
Email = groupings.Key.Email,
Phone = groupings.Key.Phone,
Password = groupings.Key.CampusName,
IsGPA = groupings.Key.IsGPA,
IsActive = groupings.Key.IsActive,
StripeId = groupings.Key.StripeId,
CreatedOn = groupings.Key.CreatedOn,
Average = groupings.Average(p=>Convert.ToDecimal(p.StudentReviewRating))
});
But it is saying Registration does not contain a definition for 'StudentReviewRating'..
What is wrong?
how about grouping by tutor, calculate the average as total ratings/number of ratings
var query = from request in data
group request by request.TutorId into groupings
let total = groupings.Sum(p=>p.StudentReviewRating)
let number = groupings.Count()
let average = (decimal)total/number
select new
{
TutorId = groupings.Key,
Summary = new
{
Total = total,
Number = number,
Average = average
}
}
and results would look like this for the given test case
TutorId Summary
1 Total 8
Number 3
Average 2.66
2 Total 3
Number 1
Average 3
Edit extra joins and extended group by
var query = from registration in registrations
join request in requests
on registration.RegistrationId equals request.TutorId
group request by new
{
registration.RegistrationId,
registration.Name,
request.TutorId,
} into groupings
select new
{
RegistrationId = groupings.Key.RegistrationId,
TutorId = groupings.Key.TutorId,
Average = groupings.Average(p=>p.StudentReviewRating)
}
Hi you can Use this to have all you want about math here
https://numerics.mathdotnet.com/

Can I consolidate the results of my Linq to SQL query?

Can I consolidate my Linq to Sql query results as part of the query? For example the following query would return list A below. I want my list to be consolidated like list B below.
IEnumerable<JoinClass> points =
from c in db.Users2
join e in db.Categories on c.Id_Users2 equals e.FK_Users2
join f in db.Programs on e.Id_Category equals f.FK_Categories
join g in db.Points on f.Id_Programs equals g.FK_Programs
where c.EEID == UserEEIDCast
orderby g.EntryDate ascending
select new JoinClass
{
Category = e.Category,
Programs = f.Programs,
Points = g.Points,
EEID = c.EEID,
EntryDate = g.EntryDate,
Name = c.Name
return View(points);
List A
Name Program Points
Jim Running 10
Jim Running 3
Jim Walking 7
Jim Walking 4
Bob Running 2
Bob Running 1
List B
Name Program Points
Jim Running 13
Jim Walking 11
Bob Running 3
try:
points = points
.GroupBy(x => new { x.Name, x.Program } )
.Select(x => new JoinClass() {Name = x.Key.Name, Program = x.Key.Program, Points = x.Sum(y => y.Points) /* copy other properties to the new JoinClass here */ });
This code groups the result using a composite key (Name and Program), then for each group it creates a new JoinClass with Points equal to the sum of all the points in that group.

Nested stored procedures

My goal is: I have three tables dev1, PICK1, rul1, and I need my information interact between them,
An example would be this: according to the results of select rul1 table, took certain lines from dev1 table and insert them into PICK1,
then the lines of the table dev1 have to be updated to avoid getting selected again in the next select from rul1
This is the structure of the tables:
dev1 {
[delivery]
[inlist]
[scot]}
rul1{
[group],
[field],
[logical_condition]
[value]}
PICK1 {
[id_delivery]
[group_num]
[lock]}
these are some of the values that I have in rul1
[group] [field] [logical_condition] [value]
1 scot = 1
1 inlist = 0
2 scot = 2
2 inlist = 0
3 scot = 3
Then when I run this stored procedure:
BEGIN
DECLARE # max int, # count int<br />
SET # count = 1<br />
SELECT # max = max ([group]) from rul1 group by [group]
while (# count <= # max)<br />
BEGIN<br />
select field + '' + logical_condition + '' + value as [rule] from rul1 where [group]= #count<br />
SET # count = (# count + 1)<br />
END
END
I get this results for each group (1, 2, 3):
scot = 1
inlist = 0
scot = 2
inlist = 0
scot = 3
Now I want to put these results into a string to be part of the clause "where" to select the correct lines from dev1 and insert them into PICK1
then update on dev1, I guess this must be every time when I run the while of the procedure, but I dont know how to nest store procedures or
if this can be completed by other method.
every assistance will be welcome
thank you very much

Resources