WithTempQuery
需求版本:v3.2.666+
GroupBy + WithTempQuery(嵌套查询) + FromQuery + UnionAll 组合使用,会让查询功能更加强大、灵活。
#场景1:查询分组第一条记录
fsql.Select<User1>()
.Where(a => a.Id < 1000)
.WithTempQuery(a => new
{
item = a,
rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue()
})
.Where(a => a.rownum == 1)
.ToList();
提示:支持多表嵌套查询,fsql.Select<User1, UserGroup1>()
SELECT *
FROM (
SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum]
FROM [User1] a
WHERE a.[Id] < 1000
) a
WHERE (a.[rownum] = 1)
如果数据库不支持开窗函数,可以使用分组嵌套查询解决:
fsql.Select<User1>()
.Where(a => a.Id < 1000)
.GroupBy(a => a.Nickname)
.WithTempQuery(g => new { min = g.Min(g.Value.Id) })
.From<User1>()
.InnerJoin((a, b) => a.min == b.Id)
.ToList((a, b) => b);
SELECT b.[Id], b.[Nickname]
FROM (
SELECT min(a.[Id]) [min]
FROM [User1] a
WHERE a.[Id] < 1000
GROUP BY a.[Nickname] ) a
INNER JOIN [User1] b ON a.[min] = b.[Id]
#场景2:嵌套查询 + Join
WithTempQuery + From<T2> 或 FromQuery(ISelect<T2>) 可实现无限联表
fsql.Select<User1>()
.Where(a => a.Id < 1000)
.WithTempQuery(a => new
{
item = a,
rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue()
})
.Where(a => a.rownum == 1)
//.From<UserExt>() //普通联表
.FromQuery(fsql.Select<UserExt>().Where(b => b.Id > 0)) //子查询联表
//.FromQuery(fsql.Select<UserExt, UserGroup, xxx>() //子多表查询联表
// .WithTempQuery((a,b,c) => new { ... }))
.InnerJoin((a, b) => a.item.Id == b.UserId)
.ToList((a, b) => new
{
user = a.item,
rownum = a.rownum,
userext = b
});
SELECT ...
FROM (
SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum]
FROM [User1] a
WHERE a.[Id] < 1000 ) a
INNER JOIN (
SELECT a.[UserId], a.[Remark]
FROM [TwoTablePartitionBy_UserExt] a
WHERE (a.[UserId] > 0) ) b ON a.[Id] = b.[UserId]
WHERE (a.[rownum] = 1)
#场景3:分组查询嵌套
fsql.Select<User1>()
.WithTempQuery(a => new
{
user = a,
rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue()
})
.Where(a => a.rownum == 1)
.FromQuery(fsql.Select<UserExt>().Where(b => b.UserId > 0)
.GroupBy(b => new { b.UserId, b.Remark })
.WithTempQuery(b => new { b.Key, sum1 = b.Sum(b.Value.UserId) }))
.InnerJoin((a, b) => a.user.Id == b.Key.UserId)
.Where((a, b) => a.user.Nickname == "name03" || a.user.Nickname == "name02")
.ToList((a, b) => new
{
user = a.user,
rownum = a.rownum,
groupby = b
});
SELECT ...
FROM (
SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum]
FROM [User] a ) a
INNER JOIN (
SELECT a.[UserId], a.[Remark], sum(a.[UserId]) [rownum]
FROM [UserExt] a
WHERE (a.[UserId] > 0)
GROUP BY a.[UserId], a.[Remark] ) b ON a.[Id] = b.[UserId]
WHERE (a.[rownum] = 1) AND ((a.[Nickname] = N'name03' OR a.[Nickname] = N'name02'))