With the following table:
+-------------+-----------+---------+
| Parent_ID | Item_ID | Count |
+-------------+-----------+---------+
| 1 | 1 | 1 |
| 1 | 1 | 5 |
| 1 | 1 | 4 |
| 1 | 2 | 7 |
| 1 | 2 | 2 |
| 2 | 1 | 2 |
| 2 | 1 | 3 |
| 2 | 2 | 2 |
| 2 | 2 | 4 |
+-------------+-----------+---------+
I would like to get the highest available count for given Parent_ID and Item_ID, like the following:
+-------------+-----------+---------+
| Parent_ID | Item_ID | Count |
+-------------+-----------+---------+
| 1 | 1 | 5 |
| 1 | 2 | 7 |
| 2 | 1 | 3 |
| 2 | 2 | 4 |
+-------------+-----------+---------+
How would I go about doing this using LINQ/SQL in C#? For example, I would like the highest item counts for parent id 1. This would be something like:
int parentId = 1;
var counts = from c in database.Items where parentId == c.parentId
//this gets all counts from items for parent id 1, but I am just looking
//for the highest count per item for parent id 1
SELECT Parent_ID, Item_ID, MAX(Count)
FROM ...
GROUP BY Parent_Id, Item_ID
select parent_id,
item_id,
max(count) as count
from your_table
group by parent_id, item_id
To group by multiple fields, you can group using an anonymous object:
var counts = from item in database.Items
group item by new { item.ParentId, item.ItemId } into itemGroup
select new Item()
{
ParentId = itemGroup.Key.ParentId,
ItemId = itemGroup.Key.ItemId,
Count = itemGroup.Max(x => x.Count)
};
Using LINQ2SQL I think you want something like:
var counts = database.Items.GroupBy(p => p.parentId).Max(p => p.Key);
Related
I need to concatenate multiple columns values to single value (separated with coma for example). I can do it by string_agg(u.name, ',') as Users in PostgreSql. I tried do it in linq query syntax but I failed - all time I just get list with split values instead of one row with values concatenated in one field.
Let's assume that I have only three tables:
Doc User Doc_User
+----+--------------------+ +----+-----------+ +----+-----------+
| Id | Path | | Id | Name | | DocId | UserId |
+----+--------------------+ +----+-----------+ +----+-----------+
| 1 | "C:\\Files\\A.txt" | | 1 | "Adam" | | 1 | 1 |
| 2 | "C:\\Files\\B.txt" | | 2 | "Benny" | | 1 | 2 |
| 3 | "C:\\Files\\C.txt" | | 3 | "Charlie" | | 2 | 1 |
+----+--------------------+ +----+-----------+ | 2 | 2 |
| 2 | 3 |
+-------+--------+
At the start I was trying simple join:
var model = (from d in db.Docs
join du in db.DU on d.Id equals du.DocId
join u in db.Users on du.UserId equals u.Id
select new DataModel() { DocPath = d.Path, UserName = u.Name }).ToList();
As I suspected I got list with separated rows:
C:\Files\A.txt | Adam
C:\Files\A.txt | Benny
C:\Files\B.txt | Adam
C:\Files\B.txt | Benny
C:\Files\B.txt | Charlie
But what I want to obtain is:
C:\Files\A.txt | Adam, Benny
C:\Files\B.txt | Adam, Benny, Charlie
string.Join() is not recognized by EF and I can't use it in linq queries, Aggregate() not working too. How can I achieve this?
I've prepared example for play with it: .Net Fiddle.
The code below groups the common documents by path using LINQ and then joins the grouped document's UserNames, using string.Join. I also think you don't need ToList() in this line select new DataModel() { DocPath = d.Path, UserName = u.Name }).ToList(); if you are going to use this solution because we are going to use LINQ again.
var grouped = model.GroupBy(x => x.DocPath);
foreach (var iGrouped in grouped){
string.Join(",",iGrouped.Select(x => x.UserName));
Console.WriteLine(iGrouped.Key + " | " + string.Join(",",iGrouped.Select(x => x.UserName)));
}
How could I get all rows, where my Id (it is meant to be like that) is x.
Example list:
| Id | Key | Value |
----------------------
| 0 | FName | Peter |
| 0 | LName | Griff |
| 0 | Phone | 12345 |
| 1 | FName | Sasha |
| 1 | LName | Un |
| 1 | Mail | SU#m.c|
| 2 | FName | Laura |
...
From the list I want to get all 0 and 1... differently to insert them into Sharepoint list.
This data has been inserted to this Collection before and Id is used to keep information for specific person.
All I could come up currently is to use loops, to do that
for (int i = 0; i < _dataVm.ADData.Count; i++)
{
foreach (DataFromAD k in _dataVm.ADData)
{
// Not sure, how could I sort out specific data here
}
}
You have to group data on Id using groupby to get seperated items by Id:
var result = from d in _dataVm.ADData
group d by d.Id into g
select new
{
Id = g.Key,
Data = g.ToList()
}
I have multiple tables and made 2 sub-selects (UserRecord,CustomerRecord) that i would like to merge into 1 table
UserRecord
========================
| RecordID | UserName |
========================
| 1 | Sara |
| 1 | Tom |
| 2 | Sara |
| 2 | Kurt |
| 3 | Fre |
========================
Table: CustomerRecord
============================
| RecordID | CustomerName |
============================
| 1 | Jef |
| 2 | Alex |
| 2 | Peter |
============================
Table: This should be the result
=======================================
| RecordID | UserName | CustomerName |
=======================================
| 1 | Sara | - |
| 1 | Tom | - |
| 1 | - | Jef |
| 2 | Sara | - |
| 2 | Kurt | - |
| 2 | - | Alex |
| 2 | - | Peter |
| 3 | Fre | - |
=======================================
- = null
I tried with left, right, left outer, right outer ... join on the 2 tables but i don't get what i would like.
SELECT *
FROM UserRecord AS ur
INNER JOIN CustomerRecord AS cr ON ur.RecordID = cr.RecordID;
What you want is not a join, but a UNION:
SELECT RecordID, UserName, NULL AS CustomerName FROM UserRecord
UNION
SELECT RecordID, NULL AS UserName, CustomerName FROM CustomerRecord
... which just appends records from the two tables.
I'd just add that the order will not be the one you have shown in your expected result. If order is important then you should SELECT from this UNION and add an explicit ORDER BY clause on this outer select. Something like:
SELECT * FROM (
SELECT RecordID, UserName, NULL AS CustomerName FROM UserRecord
UNION
SELECT RecordID, NULL AS UserName, CustomerName FROM CustomerRecord
) ORDER BY RecordID, UserName, CustomerName
You can use a simple union
select recordid, username, null as customername from userrecord
union
select recordid, null, customername from customerrecord
I have two datasets that look like this:
+------------------------------------+
| Products |
+------------------------------------+
| Id | Name | Price |
+------------------------------------+
| 1 | apples | 1.00 |
| 2 | oranges | 2.00 |
| 3 | pomengrate | 3.00 |
+------------------------------------+
+-------------------------------+
| Sales |
+-------------------------------+
| CustId | ProductId | Quantity |
+-------------------------------+
| 1 | 1 | 5 |
| 1 | 2 | 4 |
| 1 | 3 | 2 |
| 2 | 1 | 8 |
| 2 | 3 | 7 |
+-------------------------------+
I want to get the amount that each customer is spending, essentially ending up with a result like this:
+----------------+
| CustId | Total |
+----------------+
| 1 | 19.00 |
| 2 | 29.00 |
+----------------+
I can do a sum across a single table but the Sum method in LINQ takes a lambda with only one argument: the reference to the table that the values being summed are in. These values are in different tables. How do I sum these together?
var totals =
from sale in Sales
group sale by sale.CustId into custSales
select new
{
CustId = custSales.Key,
Total = (
from custSale in custSales
select custSale.Product.Price *
custSale.Quantity)
.Sum()
};
Give this a shot. It gives the results you were looking for:
var results = sales.Join(products,
sale => sale.ProductID,
product => product.ID,
(sale, product) => new { CustID = sale.CustID, Total = sale.Quantity * product.Price })
.GroupBy(r => r.CustID)
.Select(g => new { CustID = g.Key, Total = g.Sum(gt => gt.Total) });
For completeness sake, here's the query syntax version (utilizing joins as opposed to a subselect):
var totals =
from sale in sales
join prod in product on sale.ProductId equals prod.Id
let saleProds = new { sale.CustId, Total = prod.Price * sale.Quantity }
group saleProds by saleProds.CustId into custSale
select new { Customer = custSale.Key, Total = custSale.Sum(tr => tr.Total) };
The key part is that you need to somehow transform the joined collection results (sale and prod) into a single entity that can then be grouped by.
Here is my problem. i have 3-5 persons that is going to set a grade on one person and they use their own individual row to do so, and what I'm having trouble to do is to sum and average the grade from individual data across multiple rows on the same table.
in the select new statement i have made a pseudo answer of what i want
var users = from workRew in db.Reviews
select new
{
UserID = workRew.UserID.DistinctOfSomeSort
AvgGrade = workRew.Grade.Sum/CountOfSomeSort
};
Here i a illustration.
So if i have this table
| SomeID | UserID | Grade |
| 1 | 2 | 3 |
| 2 | 3 | 1 |
| 3 | 2 | 1 |
And this is the output i want from the LINQ query on the above (In theory ateast)
| UserID | AvgGrade |
| 2 | 2 |
| 3 | 1 |
EDIT: Simplified the whole case, to a great extent.
It should look something like this fragment:
group by user.UserID
select new
{
User = user.UserID
TotGradeCount = workRew.Grade.Sum()
Graders = workRew.Grade.Count()
}