我有一个包含交易的表,类似于:
--REQUEST_ID----ITEM_ID----ITEM_STATUS_CD----EXECUTION_DTTM
1 1 1 2016-08-29 12:36:07.000
1 2 0 2016-08-29 12:37:07.000
2 3 5 2016-08-29 13:37:07.000
2 4 1 2016-08-29 15:37:07.000
2 5 10 2016-08-29 15:41:07.000
3 6 0 2016-08-29 15:41:07.000
我想要的是在表格中显示在Request_ID中有多少成功/警告/错误以及最新交易的结束时间:
--REQUEST_ID--Transactions----------EndTime----------Success----Warning----Error
1 2 2016-08-29 12:37:07.000 50 50 0
2 3 2016-08-29 15:41:07.000 0 33 66
3 1 2016-08-29 15:41:07.000 100 0 0
我有以下slq所需的表格,但我不知道如何在linq中做到这一点(C#)....任何人?
SELECT distinct t1.[REQUEST_ID],
t2.Transactions,
t2.EndTime,
t2.Success,
t2.Warning,
t2.Error
FROM [dbo].[jp_R_ITEM] t1 inner join(
select top(100) max([EXECUTION_DTTM]) EndTime, REQUEST_ID,
count([ITEM_ID]) as Transactions,
coalesce(count(case when [ITEM_STATUS_CD] = 0 then 1 end), 0) * 100 / count([ITEM_ID]) as Success,
coalesce(count(case when [ITEM_STATUS_CD] = 1 then 1 end), 0) * 100 / count([ITEM_ID]) as Warning,
coalesce(count(case when [ITEM_STATUS_CD] > 1 then 1 end), 0) * 100 / count([ITEM_ID]) as Error
from [dbo].[jp_R_ITEM] group by REQUEST_ID order by REQUEST_ID desc) t2 on t1.[REQUEST_ID] = t2.REQUEST_ID and t1.[EXECUTION_DTTM] = t2.EndTime
答案 0 :(得分:0)
map.merge("car", 100, Integer::sum);
map.merge("car", 20, Integer::sum);
System.out.println(map); // {car=120}
答案 1 :(得分:0)
所以Transactions
所有RequestId
1,你想要制作一个元素。这个元素应该有RequestId
,在这种情况下是1,它应该具有所有ExecutionDttms
的最新值或具有RequestId
的事务,最后,来自您想要的所有交易一定比例的成功,警告和错误
对于使用RequestId 2的交易,以及使用RequestId 3的交易等,您需要类似的东西。
每当你看到类似于:"我想将序列中的所有项目分组到一个对象中时#34;你应该立即想到GroupBy。
这个对象可能是一个非常复杂的对象,一个List,一个Dictionary或一个具有很多属性的类的对象
因此,让我们首先制作具有相同RequestId的交易组:
var groupsWithSameRequestId = Transactions
.GroupBy(transaction => transaction.RequestId);
每个群组都有Key
,这是群组中所有元素的RequestId
。每个 <(不)拥有此RequestId
值的所有Transaction的序列。
您希望将每个组转换为一个结果元素。每个结果元素
有一个属性RequestId
以及包含此RequestId
的交易数。
RequestId
是群组的Key
,TransactionCount
当然是群组中的元素数量
var result = groupsWithSameRequestId.Select(group => new
{
RequestId = group.Key,
TransactionCount = group.Count(),
...
};
那是最容易的。
Endtime是组中所有ExecutionDttm的最大值。
var result = groupsWithSameRequestId.Select(group => new
{
RequestId = group.Key,
TransactionCount = group.Count(),
EndTime = group.Select(groupElement => groupElement.ExecutionDttm).Max(),
...
};
可能是您的数据查询转换器不允许Max on Datetime。在这种情况下:顺序下降并采取第一个:
EndTime = group.Select(groupElement => groupElement.ExecutionDttm)
.OrderByDescenting(date => date)
.First(),
First()
已经足够,FirstOrDefault()
不需要,我们知道没有任何组没有任何元素
我们为最后一个节省了最困难/最有趣的部分。您需要成功/警告/错误的百分比,即ItemStatus
0/1 /更多的元素数。
Success = 100 * group
.Where(groupElement => groupElement.ItemStatus == 0).Count()
/group.Count(),
Warning = 100 * group
.Where(groupElement => groupElement.ItemStatus == 1).Count()
/group.Count(),
Error = 100 * group
.Where(groupElement => groupElement.ItemStatus > 1).Count()
/group.Count(),
这取决于你的IQueryable / DbContext有多聪明。但乍一看似乎经常调用Count()。引入额外的Select
会阻止此操作。
所以将这一切结合到一个LINQ语句中:
var result = Transactions
.GroupBy(transaction => transaction.RequestId)
.Select(group => new
{
RequestId = group.Key
GroupCount = group.Count(),
SuccessCount = group
.Where(groupElement => groupElement.ItemStatus == 0).Count(),
WarningCount = group
.Where(groupElement => groupElement.ItemStatus == 1).Count(),
ErrorCount = group
.Where(groupElement => groupElement.ItemStatus > 1).Count(),
EndTime = group
.Select(groupElement => groupElement.ExecutionDttm)
.Max(),
})
.Select(item => new
{
RequestId = item.RequestId,
TransactionCount = item.GroupCount,
EndTime = item.EndTime,
SuccessCount = 100.0 * item.SuccesCount / item.GroupCount,
WarningCount = 100.0 * item.WarningCount / item.GroupCount,
ErrorCount = 100.0 * item.ErrorCount / item.GroupCount,
}