将简单的 Left Outer Join 和 group by SQL 语句转换为 Linq
Convert simple Left Outer Join and group by SQL statement into Linq
2 tables: 用户和警报
Table:用户
用户ID(整数),
全名(varchar)
Table:报警
分配给(整数),
已解决(布尔)
查询:
SELECT u.Fullname, COUNT(resolved) as Assigned, SUM(CONVERT(int,Resolved)) as Resolved, COUNT(resolved) - SUM(CONVERT(int,Resolved)) as Unresolved
FROM Alarm i LEFT OUTER JOIN Users u on i.AssignedTo = u.UserID
GROUP BY u.Fullname
结果:
Fullname Assigned Resolved Unresolved
User1 204 4 200
User2 39 9 30
User3 235 200 35
User4 1 0 1
User5 469 69 400
我这辈子都想不出如何将其变成 Linq 查询。我在使用分组功能时遇到问题。
我看了无数的例子,none 有我的 Left Outer join 和分组的组合,或者它们太复杂了,我不知道如何让它与我的一起工作。如有任何帮助,我们将不胜感激!!!
更新:
我可能不清楚我在寻找什么。我正在寻找按 AssignedTo 列分组的警报,它是一个用户标识...除此之外,我想用位于用户 table 中的 FullName 替换该用户标识。有人发布并删除了一些接近的东西,除了它给了我用户 table 中的所有用户,这不是我要找的..
更新 2: 请参阅下面的回答
试试这个:
from u in context.User
join a in context.Alarm on u.UserID equals a.AssignedTo into g1
from g2 in g1.DefaultIfEmpty()
group g2 by u.Fullname into grouped
select new { Fullname = grouped.Key, Assigned = grouped.Count(t=>t.Resolved != null), Resolved = grouped.Sum
(t => int.Parse(t.Resolved)), Unresolved = (grouped.Count(t=>t.Resolved != null) - grouped.Sum
(t => int.Parse(t.Resolved)))}
我想在 Linq 中这个查询不一定要使用 "Grouping" 因为 "LEFT JOIN" + "GROUP BY" 的组合将它们更改为 "INNER JOIN".
var results =
from u in users
join a in alarms on u.UserID equals a.AssignedTo into ua
select new
{
Fullname = u.FullName,
Assigned = ua.Count(),
Resolved = ua.Count(a => a.Resolved),
Unresolved = ua.Count(a => !a.Resolved)
};
foreach (var r in results)
{
Console.WriteLine(r.Fullname + ", " + r.Assigned + ", " + r.Resolved + ", " + r.Unresolved);
}
假设您有以下型号:
这是闹钟的型号:
public class Alarm
{
public int id { get; set; }
public int AssignedTo { get; set; }
[ForeignKey("AssignedTo")]
public virtual User User { get; set; }
public bool Resolved { get; set; }
}
这是用户的模型:
public class User
{
public int UserID { get; set; }
public string FullName { get; set; }
public virtual ICollection<Alarm> Alarms { get; set; }
public User()
{
Alarms = new HashSet<Alarm>();
}
}
这是将保存每个用户的警报统计信息的模型:
public class UserStatistics
{
public string FullName { get; set; }
public int Assigned { get; set; }
public int Resolved { get; set; }
public int Unresolved { get; set; }
}
然后您可以执行以下操作:
var query = context.Users.Select(
user =>
new UserStatistics
{
FullName = user.FullName,
Assigned = user.Alarms.Count,
Resolved = user.Alarms.Count(alarm => alarm.Resolved),
Unresolved = user.Alarms.Count(alarm => !alarm.Resolved)
});
var result = query.ToList();
顺便说一句,您还可以修改查询并删除 Unresolved = user.Alarms.Count(alarm => !alarm.Resolved)
,然后将 Unresolved
属性 计算为这样的 属性:
public class UserStatistics
{
public string FullName { get; set; }
public int Assigned { get; set; }
public int Resolved { get; set; }
public int Unresolved
{
get { return Assigned - Resolved; }
}
}
这将使生成的 SQL 查询更简单。
我终于明白了。
这个:
var results = alarms.GroupBy(x => x.AssignedTo)
.Join(users, alm => alm.Key , usr => usr.UserID, (alm, usr) => new {
Fullname = usr.FullName,AssignedNum = alm.Count(),
Resolved = alm.Where(t=>t.resolved == true).Select(y => y.resolved).Count(),
Unresolved = alm.Where(t=>t.resolved == false).Select(y => y.resolved).Count() });
转载:
SELECT u.Fullname, COUNT(resolved) as Assigned, SUM(CONVERT(int,Resolved)) as Resolved,
COUNT(resolved) - SUM(CONVERT(int,Resolved)) as Unresolved
FROM Alarm i LEFT OUTER JOIN Users u on i.AssignedTo = u.UserID
GROUP BY u.Fullname
结果按 AssignedTo (int) 分组,但未选择 AssignedTo。相反,全名是从加入的用户 table.
中选择的
非常感谢所有试图提供帮助的人!我从你的回答中学到了很多。
为了加分,我该如何用 SQL 语法来写我的 lamdbda 答案?
2 tables: 用户和警报
Table:用户 用户ID(整数), 全名(varchar)
Table:报警 分配给(整数), 已解决(布尔)
查询:
SELECT u.Fullname, COUNT(resolved) as Assigned, SUM(CONVERT(int,Resolved)) as Resolved, COUNT(resolved) - SUM(CONVERT(int,Resolved)) as Unresolved
FROM Alarm i LEFT OUTER JOIN Users u on i.AssignedTo = u.UserID
GROUP BY u.Fullname
结果:
Fullname Assigned Resolved Unresolved
User1 204 4 200
User2 39 9 30
User3 235 200 35
User4 1 0 1
User5 469 69 400
我这辈子都想不出如何将其变成 Linq 查询。我在使用分组功能时遇到问题。 我看了无数的例子,none 有我的 Left Outer join 和分组的组合,或者它们太复杂了,我不知道如何让它与我的一起工作。如有任何帮助,我们将不胜感激!!!
更新: 我可能不清楚我在寻找什么。我正在寻找按 AssignedTo 列分组的警报,它是一个用户标识...除此之外,我想用位于用户 table 中的 FullName 替换该用户标识。有人发布并删除了一些接近的东西,除了它给了我用户 table 中的所有用户,这不是我要找的..
更新 2: 请参阅下面的回答
试试这个:
from u in context.User
join a in context.Alarm on u.UserID equals a.AssignedTo into g1
from g2 in g1.DefaultIfEmpty()
group g2 by u.Fullname into grouped
select new { Fullname = grouped.Key, Assigned = grouped.Count(t=>t.Resolved != null), Resolved = grouped.Sum
(t => int.Parse(t.Resolved)), Unresolved = (grouped.Count(t=>t.Resolved != null) - grouped.Sum
(t => int.Parse(t.Resolved)))}
我想在 Linq 中这个查询不一定要使用 "Grouping" 因为 "LEFT JOIN" + "GROUP BY" 的组合将它们更改为 "INNER JOIN".
var results =
from u in users
join a in alarms on u.UserID equals a.AssignedTo into ua
select new
{
Fullname = u.FullName,
Assigned = ua.Count(),
Resolved = ua.Count(a => a.Resolved),
Unresolved = ua.Count(a => !a.Resolved)
};
foreach (var r in results)
{
Console.WriteLine(r.Fullname + ", " + r.Assigned + ", " + r.Resolved + ", " + r.Unresolved);
}
假设您有以下型号:
这是闹钟的型号:
public class Alarm
{
public int id { get; set; }
public int AssignedTo { get; set; }
[ForeignKey("AssignedTo")]
public virtual User User { get; set; }
public bool Resolved { get; set; }
}
这是用户的模型:
public class User
{
public int UserID { get; set; }
public string FullName { get; set; }
public virtual ICollection<Alarm> Alarms { get; set; }
public User()
{
Alarms = new HashSet<Alarm>();
}
}
这是将保存每个用户的警报统计信息的模型:
public class UserStatistics
{
public string FullName { get; set; }
public int Assigned { get; set; }
public int Resolved { get; set; }
public int Unresolved { get; set; }
}
然后您可以执行以下操作:
var query = context.Users.Select(
user =>
new UserStatistics
{
FullName = user.FullName,
Assigned = user.Alarms.Count,
Resolved = user.Alarms.Count(alarm => alarm.Resolved),
Unresolved = user.Alarms.Count(alarm => !alarm.Resolved)
});
var result = query.ToList();
顺便说一句,您还可以修改查询并删除 Unresolved = user.Alarms.Count(alarm => !alarm.Resolved)
,然后将 Unresolved
属性 计算为这样的 属性:
public class UserStatistics
{
public string FullName { get; set; }
public int Assigned { get; set; }
public int Resolved { get; set; }
public int Unresolved
{
get { return Assigned - Resolved; }
}
}
这将使生成的 SQL 查询更简单。
我终于明白了。
这个:
var results = alarms.GroupBy(x => x.AssignedTo)
.Join(users, alm => alm.Key , usr => usr.UserID, (alm, usr) => new {
Fullname = usr.FullName,AssignedNum = alm.Count(),
Resolved = alm.Where(t=>t.resolved == true).Select(y => y.resolved).Count(),
Unresolved = alm.Where(t=>t.resolved == false).Select(y => y.resolved).Count() });
转载:
SELECT u.Fullname, COUNT(resolved) as Assigned, SUM(CONVERT(int,Resolved)) as Resolved,
COUNT(resolved) - SUM(CONVERT(int,Resolved)) as Unresolved
FROM Alarm i LEFT OUTER JOIN Users u on i.AssignedTo = u.UserID
GROUP BY u.Fullname
结果按 AssignedTo (int) 分组,但未选择 AssignedTo。相反,全名是从加入的用户 table.
中选择的非常感谢所有试图提供帮助的人!我从你的回答中学到了很多。
为了加分,我该如何用 SQL 语法来写我的 lamdbda 答案?