I will appreciate help on writing the following SQL query with multiple count into a single LINQ expression
select count(MemoNo) as totalOrder,
count(distinct shopId) as shops,
sum(TotalAmount) as totalAmount
from Sales;
Sample data
| MemoNo | shopId | TotalAmount |
|-------------------------------|
| a10| s2| 200|
| a11| s2| 220|
| a12| s3| 100|
| a13| s3| 20|
| a14| s3| 100|
| a15| s4| 50|
| a16| s4| 20|
| a17| s4| 90|
Sample output should look like this
| totalOrder | shops | totalAmount |
|------------|-------|-------------|
| 8 | 3 | 800|
Try this way
var totalOrder = Sales.Select(p => p.MemoNo).Count();
var shop = Sales.Select(p => p.shopId).Distinct().Count();
var totalAmount = Sales.Sum(p => p.TotalAmount);
Updated
Demo on dotnet fiddle
var tempData = Sales.GroupBy(p => p.shopId).Select(g => new
{
shops = g.Count(),
totalAmount = g.Sum(p => p.TotalAmount),
totalOrder = g.Count()
});
var result = new
{
totalOrder = tempData.Sum(p => p.totalOrder),
shops = tempData.Count(),
totalAmount = tempData.Sum(p => p.totalAmount)
};
// Output: { totalOrder = 8, shops = 3, totalAmount = 800 }
I'm trying to get the output of the following query into a Linq query
SELECT SearchQueries.Query,
Clicks.Name,
COUNT (SearchQueries.Query) AS Hits
FROM SearchQueries
INNER JOIN Clicks ON Clicks.SearchqueryId = SearchQueries.Id
GROUP BY SearchQueries.Query, Clicks.Name
ORDER BY Hits DESC
But I can't seem to figure out how to do this;
this is what I have so far
var result =
_db.Clicks.Select(q => q)
.GroupBy(q => q.Name, g => g.Searchquery.Query)
.ToDictionary(g=> g.Key, g => g);
but how would I continue?
the result is something like this:
+---------------+-------------------+------+
|Query | Name | Hits |
+---------------+-------------------+------+
|tag | dnfsklmfnsd | 53 |
|tag2 | dgsqfsdf | 17 |
+---------------+-------------------+------+
The original tables looks like following
SearchQueries;
+---+-------+
|Id | Query |
+---+-------+
| 1 | tag | x 53
| 2 | tag2 | x 17
+---+-------+
Clicks;
+---+-------------------+---------------+
|Id | Name | SearchqueryId |
+---+-------------------+---------------+
| 1 | dnfsklmfnsd | 1 |
| 2 | dgsqfsdf | 2 |
+---+-------------------+---------------+
Try to use GroupBy and Count: (I changed the order to using SearchQueries as "base table" in the expression, just to make it more easy to compare to the SQL-statement)
var result =
_db.SearchQueries
.GroupBy(sq => new { name = sq.Clicks.Name, query = sq.Query)
.Select(sq => new {
Query = sq.Query,
Name = sq.Clicks.Name,
Hits = sq.Count()
})
.OrderByDescending(sq => sq.Hits);
Well, if you have a navigation property Searchquery on Click, as it looks like, you can do
var result =
_db.Clicks
.GroupBy(m => new {name = m.Name, query = m.Searchquery.Query)
.Select(g => new {
Query = g.Key.query,
Name = g.Key.name,
Hits = g.Count()
});
I have two tables:
Banner
--------------------------------------------------------|
BId | Name | Link | Image | AltText| Target | BActive|
--------------------------------------------------------
|1 | hello| http| a.jpg |helloimg| | 1 |
--------------------------------------------------------
Tracking
------------------------------------------------------
|TId | BId| ICount| CCount| CreateDate |
------------------------------------------------------
|1 | 1 | 102 | 300 | 2015-11-17 00:00:000 |
|2 | 1 | 182 | 100 | 2015-11-14 00:00:000 |
|3 | 1 | 192 | 200 | 2015-11-12 00:00:000 |
------------------------------------------------------
I want to find the Sum of ICount and CCound for each BId between 2015-11-12 and 2015-11-15.
Here is the code I have tried:
from p in Bannertables
join q in BannerTrackings
on p.BannerId equals q.BannerId
group p by p.BannerId into myTab
select new {
BannerId = myTab.Key,
ImpressionCount = myTab.Sum( x=> x.ImpressionCount),
ClickCount = myTab.Sum(x => x.ClickCount)
};
How do I sort the result according to the date range I specified?
Add the followingwhere to your query:
var d1 = new DateTime(2015, 11, 12);
var d2 = new DateTime(2015, 11, 15);
var query=from p in Bannertables
join q in BannerTrackings
on p.BannerId equals q.BannerId
where q.CreateDate>=d1 && q.CreateDate<=d2
group q by p.BannerId into myTab
select new {
BannerId = myTab.Key,
ImpressionCount = myTab.Sum( x=> x.ImpressionCount),
ClickCount = myTab.Sum(x => x.ClickCount)
};
Update
If you want to get access to the Banner's properties, include it in the group as I show below:
var d1 = new DateTime(2015, 11, 12);
var d2 = new DateTime(2015, 11, 15);
var query=from p in Bannertables
join q in BannerTrackings
on p.BannerId equals q.BannerId
where q.CreateDate>=d1 && q.CreateDate<=d2
group new{Banner=p,Tracking=q} by p.BannerId into myTab
select new {
BannerId = myTab.Key,
Bannername=myTab.Select(e=>e.Banner.Name).FirstOrDefault(),
ImpressionCount = myTab.Sum( x=> x.Tracking.ImpressionCount),
ClickCount = myTab.Sum(x => x.Tracking.ClickCount)
};
But if you only want the banner name this is even better:
var d1 = new DateTime(2015, 11, 12);
var d2 = new DateTime(2015, 11, 15);
var query=from p in Bannertables
join q in BannerTrackings
on p.BannerId equals q.BannerId
where q.CreateDate>=d1 && q.CreateDate<=d2
group q by new {p.BannerId,p.Name} into myTab
select new {
BannerId = myTab.Key.BannerId,
BannerName=myTab.Key.Name,
ImpressionCount = myTab.Sum( x=> x.ImpressionCount),
ClickCount = myTab.Sum(x => x.ClickCount)
};
I have the following Tables
+--------+ +---------+ +---------+
| Class |1 N| Student |1 N| Test |
+--------+<--->+---------+<--->+---------+
|ClassID | |ClassID | |TestID |
|Desc | |StudentID| |StudentID|
+--------+ |Name | |Name |
+---------+ |Score |
+---------+
and I need to determine the total score of the first student of a class. there can be one, multiple or none existing tests for this student
So the result should look like
ClassDesc | StudentName | ScoreCount
----------+-------------+-----------
C1 | Max | 201
C2 | Tom | null
I have the following code
using (myEntities ctx = new myEntities())
{
var Reslut = ctx.Class
.Select(x => new
{
ClassDesc = x.Desc,
StudentName = x.Student.FirstOrDefault().Name,
ScoreCount = x.Student.FirstOrDefault().Test.Sum(t => t.Score) //Error here
}).ToList();
}
but it gives me the error
Unknown column 'Project1.ClassID' in 'where clause'
Try the following:
var result = (from cls in ctx.Class
join stdt in ctx.Student on cls.ClassID equals stdt.ClassID
select new
{
ClassDesc = cls.Desc,
StudentName = stdt.Name,
ScoreCount = stdt.Test.Sum(t => t.Score)
}).ToList();
Which should generate SQL similar to the following:
SELECT
Class.ClassID,
Class.[Desc],
Student.Name,
(
SELECT
SUM(Test.Score)
FROM dbo.Test
WHERE Student.StudentID = Test.StudentID
) AS ScoreSum
FROM dbo.Class
INNER JOIN dbo.Student ON Class.ClassID = Student.ClassID
I have a users table:
Id | Name | Age
--------------------
1 | Steve | 21
2 | Jack | 17
3 | Alice | 25
4 | Harry | 14
I also have a table containing additional user info:
UId | Key | Value
----------------------
1 | Height | 70
2 | Height | 65
2 | Eyes | Blue
4 | Height | 51
3 | Hair | Brown
1 | Eyes | Green
The UId column links to the Id column in the users table. As you can see, not all users have the same additional info present. Alice doesn't have a height value, Jack is the only one with an eye color value etc.
Is there a way to combine this data into one table dynamically using C# and LINQ queries so that the result is something like this:
Id | Name | Age | Height | Eyes | Hair
------------------------------------------
1 | Steve | 21 | 70 | Green |
2 | Jack | 17 | 65 | Blue |
3 | Alice | 25 | | | Brown
4 | Harry | 14 | 51 |
If a user does not have a value for the column, it can remain empty/null. Does this require some sort of data pivoting?
For the case, your user info fields are constant:
var result = users.GroupJoin(details,
user => user.Id,
detail => detail.Id,
(user, detail) => new
{
user.Id,
user.Name,
user.Age,
Height = detail.SingleOrDefault(x => x.Key == "Height").Value,
Eyes = detail.SingleOrDefault(x => x.Key == "Eyes").Value,
Hair = detail.SingleOrDefault(x => x.Key == "Hair").Value,
});
You can do it by utilising GroupJoin, example:
var users = new List<Tuple<int, string, int>> {
Tuple.Create(1, "Steve", 21),
Tuple.Create(2, "Jack", 17),
Tuple.Create(3, "Alice", 25),
Tuple.Create(4, "Harry", 14)
};
var userInfos = new List<Tuple<int, string, string>> {
Tuple.Create(1, "Height", "70"),
Tuple.Create(2, "Height", "65"),
Tuple.Create(2, "Eyes", "Blue"),
Tuple.Create(4, "Height", "51"),
Tuple.Create(3, "Hair", "Brown"),
Tuple.Create(1, "Eyes", "Green"),
};
var query = users.GroupJoin(userInfos,
u => u.Item1,
ui => ui.Item1,
(u, infos) => new { User = u, Infos = infos });
var result = query.Select(qi => new
{
Id = qi.User.Item1,
Name = qi.User.Item2,
Age = qi.User.Item3,
Height = qi.Infos.Where(i => i.Item2 == "Height").Select(i => i.Item3).SingleOrDefault(),
Eyes = qi.Infos.Where(i => i.Item2 == "Eyes").Select(i => i.Item3).SingleOrDefault(),
Hair = qi.Infos.Where(i => i.Item2 == "Hair").Select(i => i.Item3).SingleOrDefault()
});
First of all I have grouped the user details data using Feature (I have renamed the Key property with Feature to avoid confusion) & UId then I have used group join to combine both results using into g. Finally retrieved the result using specified feature.
var result = from user in users
join detail in details.GroupBy(x => new { x.UId, x.Feature })
on user.Id equals detail.Key.UId into g
select new
{
Id = user.Id,
Name = user.Name,
Age = user.Age,
Height = g.FirstOrDefault(z => z.Key.Feature == "Height") != null ?
g.First(z => z.Key.Feature == "Height").First().Value : String.Empty,
Eyes = g.FirstOrDefault(z => z.Key.Feature == "Eyes") != null ?
g.First(z => z.Key.Feature == "Eyes").First().Value : String.Empty,
Hair = g.FirstOrDefault(z => z.Key.Feature == "Hair") != null ?
g.First(z => z.Key.Feature == "Hair").First().Value : String.Empty,
};
I am getting following output:-
Here is the complete Working Fiddle.
Try this
var list = (from u in context.users
join ud in context.UserDetails on u.Id equals ud.UId
select new
{
u.Id,
u.Name,
u.Age,
ud.Key,
ud.Value
});
var finallist = list.GroupBy(x => new { x.Id, x.Name,x.Age}).Select(x => new
{
x.Key.Id,
x.Key.Name,
x.Key.Age,
Height = x.Where(y => y.Key == "Height").Select(y => y.Value).FirstOrDefault(),
Eyes = x.Where(y => y.Key == "Eyes").Select(y => y.Value).FirstOrDefault(),
Hair = x.Where(y => y.Key == "Hair").Select(y => y.Value).FirstOrDefault()
}).ToList();
try this query
var objlist=( form a in contex.user
join b in contex.UserDetails on a.id equals a.Uid into gj
from subpet in gj.DefaultIfEmpty()
select new { Id=a.id, Name=a.name, Age=a.age, Height =subpet.Height,Eyes=subpet.Eyes, Hair=subpet.Hair}).ToList();