I have 2 tables, for example let's assume that this is the data:
users table:
------------------------------
| user_id | username |
------------------------------
| 1 | danny |
| 2 | george |
| 3 | lana |
| 4 | kim |
| 5 | tim |
------------------------------
users_logins table:
-----------------------------------------------
| record_id | user_id | recorder |
-----------------------------------------------
| 1 | 3 | 2012-11-06 04:18:26 |
| 2 | 3 | 2012-11-06 04:31:05 |
| 3 | 2 | 2012-11-06 03:44:22 |
| 4 | 1 | 2012-11-06 04:18:58 |
| 5 | 1 | 2012-11-06 04:30:15 |
| 6 | 3 | 2012-11-06 04:31:05 | X
| 7 | 1 | 2012-11-06 05:53:47 |
| 8 | 1 | 2012-11-06 05:55:15 | X
| 9 | 4 | 2012-11-06 05:59:31 |
| 10 | 4 | 2012-11-06 06:12:55 | X
-----------------------------------------------
I want to show 3 recent logged in users, so the result will show only the rows that marked with X right to them, or in words unique recent logins.
How would the query look like?
Try this for linq to objects
(from login in users_logins.OrderByDescending(user => user.recorder)
from user in users
where user.user_id == login.user_id
select user).Distinct().Take(3)
This query
1. first sorts on date
2. then joins sorted login data with user data,
3. then take distinct users
4. and then finally take first 3 records.
Following is alternative query
from login in users_logins.OrderByDescending(user =>user.recorder).GroupBy(user=>user.recorder).SelectMany( users=>users.First()).Take(3)
from user in users
where user.user_id == login.user_id
select user
This query
1. first sorts
2. then groups on user_id
3. then take first 3 records with different user id,
4. then joins with users data.
I think this is what you want.
var resentLogedInUsers =
users
.Join(
users_logins,
u => u.user_id,
l => l.user_id,
(u, l) => new
{
User = u,
Login = l.recorder
})
.GroupBy(j => j.User)
.Select(l => new {User = l.Key, LastLogin = l.Max(d => d.Login)})
.OrderByDescending(r => r.LastLogin)
.Take(3);
Related
I have two tables in DB Master Setup Approval and Order Details and I want check On any Master Approval Setup, this purchase order will go on relying CostCenter.
Table Master Setup Approval:
|-------|---------|-------------|-------------|---------------|---------------------|
| ID | Name | CRG_COM_ID| CRG_BRN_ID |ApprovalTypeId |CostCenter(string) |
|-------|---------|-------------|-------------|---------------|---------------------|
| 1 | Setup1 | 1 | 1 | 1 | "1,2,5,7" |
|-------|---------|-------------|-------------|---------------|---------------------|
| 2 | Setup2 | 1 | 1 | 1 | "1,3,6" |
|-------|---------|-------------|-------------|---------------|---------------------|
Table OrderDetails :
|-------|---------|-------------|-------------|------------------|
| ID | Name | CRG_COM_ID| CRG_BRN_ID |CostCenterID(long)|
|-------|---------|-------------|-------------|------------------|
| 1 | Item1 | 1 | 1 | 1 |
|-------|---------|-------------|-------------|------------------|
| 2 | Item2 | 1 | 1 | 7 |
|-------|---------|-------------|-------------|------------------|
This is my code:
var orderDetails = db.OrderDetails.Where(c => c.OrderId == orderId);
var costc = orderDetails.Select(c => c.CostCenterId.Value).ToList().ConvertAll<string>(delegate (long i) { return i.ToString(); });
var ApprovalProcess_Count12 = db.MasterSetupApproval.Where(x =>
x.CRG_COM_ID == order.CompanyId &&
(x.CRG_BRN_ID == null || x.CRG_BRN_ID == order.BranchId) &&
x.ApprovalTypeId == (int)ApprovalTypes.PO &&
x.CostCenter.Split(',').Select(aee => aee).Any(val => costc.Contains(val))
).ToList();
I am getting the following error:
LINQ to Entities does not recognize the method 'System.String[] Split(Char[])' method, and this method cannot be translated into a store expression.
Output should be:
|-------|---------|-------------|-------------|---------------|---------------------|
| ID | Name | CRG_COM_ID| CRG_BRN_ID |ApprovalTypeId |CostCenter(string) |
|-------|---------|-------------|-------------|---------------|---------------------|
| 1 | Setup1 | 1 | 1 | 1 | "1,2,5,7" |
|-------|---------|-------------|-------------|---------------|---------------------|
Assuming you are working with a badly-designed DB (as pointed out by Crowcoder) that comma-separated values should not be present in a database, you may refer this to tackle your way through.
HTH!
I have the following table:
| Id | ParentId | Version |
---------------------------
| 1 | 1 | 0 |
| 2 | 1 | 1 |
| 3 | 1 | 2 |
| 4 | 4 | 0 |
| 5 | 4 | 1 |
| 6 | 4 | 2 |
I am looking for a query (pref Linq to EF) where I can select the highest Version per group of ParentIds.
I currently have something like this:
await _context.Actions.GroupBy(a => a.ParentId)
.Select(s => s.Max(a => a.Version))
.ToListAsync();
The only problem I have is that only the version row is returned but I'd like the whole row to be returned per group.
You would need to order by descending and take the first in each group
await _context.Actions
.GroupBy(a => a.ParentId)
.Select(s => s.OrderByDescending(a => a.Version).First())
.ToListAsync();
Hiiya,
So trying to work out a query that returns a list of objects based on its max effective from date before a selected datetime.
Principle Example
+----+--------------+------------+----------------+
| id | Employee_Num | Money_Owed | Effective_From |
+----+--------------+------------+----------------+
| 1 | 1 | 10.11 | 20/10/2017 |
+----+--------------+------------+----------------+
| 2 | 1 | 15.11 | 24/10/2017 |
+----+--------------+------------+----------------+
| 3 | 1 | 20.11 | 30/10/2017 |
+----+--------------+------------+----------------+
| 4 | 2 | 6.89 | 20/10/2017 |
+----+--------------+------------+----------------+
| 5 | 2 | 9.89 | 25/10/2017 |
+----+--------------+------------+----------------+
| 6 | 2 | 12.89 | 29/10/2017 |
+----+--------------+------------+----------------+
so say I want to return each employees record as of 21/10/17 I would expect the below to be returned as a list of objects (Entities)
+----+--------------+------------+----------------+
| id | Employee_Num | Money_Owed | Effective_From |
+----+--------------+------------+----------------+
| 1 | 1 | 10.11 | 20/10/2017 |
+----+--------------+------------+----------------+
| 4 | 2 | 6.89 | 20/10/2017 |
+----+--------------+------------+----------------+
Then as of 24/10/2017
+----+--------------+------------+----------------+
| id | Employee_Num | Money_Owed | Effective_From |
+----+--------------+------------+----------------+
| 2 | 1 | 15.11 | 24/10/2017 |
+----+--------------+------------+----------------+
| 4 | 2 | 6.89 | 20/10/2017 |
+----+--------------+------------+----------------+
Im guessing the Query should be something along these lines but cant work out what it should be.
var qry = from t in db.Entity.Where(x => x.Effective_From <= as_of_date)
.OrderBy(x => x.Employee_Num)
select new Entity { *need rest of entity fields* ,effective_from = Max(e => e.Effective_From) };
Any help to finish off or point me in a different direction would be appreciated...
I believe what you'd be looking to do would involve a GroupBy expression to group by employee number, ordered by Employee number and then effective from descending, then take the first available combination.
var qry = db.Entity.Where(x => x.Effective_From <= as_of_date)
.OrderBy(x => x.Employee_Num)
.ThenByDescending(x => X.Effective_From)
.GroupBy(x => x.Employee_Num)
.Select(g => g.FirstOrDefault())
.ToList();
This is if you want the actual entities. I'd avoid doing something like "select new" for an entity as while this will contain the data of the relevant entities, they aren't the same reference as far as the context is concerned. .Select() would be used to retrieve an anonymous type suited for some logic or to populate a view model for a front end, or a DTO for an API result.
I have a DB table which has some data as follows:
LINE | QTY | USERID | DATE
-----------------------------------------
1 | 5 | qb1 | 2015-03-02 11:23:25
2 | 1 | qb2 | 2015-03-02 18:24:03
3 | 3 | ch1 | 2015-03-03 05:38:49
1 | 2 | qb1 | 2015-03-03 08:47:02
2 | 4 | qb2 | 2015-03-03 14:01:31
3 | 2 | ch1 | 2015-03-03 21:11:53
1 | 4 | qb1 | 2015-03-04 09:34:04
2 | 5 | qb2 | 2015-03-04 15:29:27
3 | 1 | ch1 | 2015-03-04 19:28:33
As you can see I have only 3 unique LINE values in the DB. I require a LINQ query to select the latest record of every line. The date can be any date, I just need the latest status of the lines based on "DATE" field.
At the moment I am doing it very roughly something like this:
var line1 = db.GetTable<lnk_sts>().Where(x=> x.LINE== 1).OrderByDescending(x => x.DATE).FirstOrDefault();
Same for the other 2. What I Require is a list of lnk_sts with only the ones with a bigger date, in this case:
LINE | QTY | USERID | DATE
---------------------------------------
1 | 4 | qb1 | 2015-03-04 09:34:04
2 | 5 | qb2 | 2015-03-04 15:29:27
3 | 1 | ch1 | 2015-03-04 19:28:33
What you need to do is, group on Line and then take the first item in group after ordering in descending.
db.GetTable<lnk_sts>()
.GroupBy(x=>x.LINE)
.Select(x=>x.OrderByDescending(o=>o.DATE).FirstOrDefault())
.ToList();
First group by the line, then order by date and take the last item.
var result = db.GetTable<lnk_sts>().GroupBy(x=> x.LINE).Select(x => x.OrderBy(y => y.Date).Last())
I am struggling with a linq query.
I would like to:
Select for each schedule_Region_ids the bins that do not fail qc (QC=1)
Select the top 3 bins that do not have QC fail mark (1) (for example, bins 3 4 and 5 if no QC mark =1)
Average the 3 selected values to create 'BaselPeak' for each schedule_Region_id.
I have tried the following code:
var categories = drugonboard
.Where(p => p.Field<int?>("QC") != 1)
.OrderByDescending(x => x.Field<int>("bin")).Take(3)
.GroupBy(t => new { ID = t.Field<int>("schedule_region_id")})
.Select(g => new
{
schedule_region_id = g.Key.ID,
BaselPeak = g.Average(p => p.Field<double>("AnalytePeak"))
});
However I end up with the top 3 schedule_region_ids and not the average of the top three bins for each schedule_region_id. If i try to GroupBy first then i get anonomous type errors.
I have a dataset which looks like this:
id | bin | AnalytePeak | QC
1 | 1 | 620 |
1 | 2 | 1020 |
1 | 3 | 681 | 1
1 | 4 | 1190 |
1 | 5 | 1200 |
---------------------------
2 | 1 | 1020 |
2 | 2 | 1076 |
2 | 3 | 1190 |
2 | 4 | 1200 |
2 | 5 | 358 | 1
---------------------------
3 | 1 | 1020 |
3 | 2 | 1076 |
3 | 3 | 1190 |
3 | 4 | 1200 |
3 | 5 | 1358 |
You need to take 3 after grouping and after sorting the child records.
var categories = drugonboard
.Where(p => p.Field<int?>("QC") != 1)
.GroupBy(t => new { ID = t.Field<int>("schedule_region_id")})
.Select(g => new {
schedule_region_id = g.Key.ID,
BaselPeak = g.OrderByDescending(x => x.Field<int>("bin"))
.Take(3)
.Average(p => p.Field<double>("AnalytePeak"))
});
This assumes:
If all bins are QC=1, then you don't want the schedule_region_id parent at all and by top 3, you mean the highest 3 bin numbers.