我一直试图想出这个问题很长一段时间......
我正在尝试查询公司的许可证使用情况。我有一个捕获数据的服务和一个SQL服务器DB来存储它。我的问题是查询数据。我认为这将是最简单的部分,但不是那么多。
示例数据
+-------------+---------+----------+------------------+
| Application | Feature | Division | RecordedTime |
+-------------+---------+----------+------------------+
| App1 | Feat1 | Div1 | 2014-01-01 00:00 |
| App1 | Feat1 | Div1 | 2014-01-01 00:00 |
| App1 | Feat1 | Div1 | 2014-01-01 00:00 |
| App1 | Feat1 | Div1 | 2014-01-01 00:00 |
| App1 | Feat1 | Div2 | 2014-01-01 00:00 |
| App1 | Feat1 | Div1 | 2014-01-01 00:05 |
| App1 | Feat1 | Div2 | 2014-01-01 00:05 |
| App1 | Feat1 | Div2 | 2014-01-01 00:05 |
| App1 | Feat2 | Div2 | 2014-01-01 00:10 |
+-------------+---------+----------+------------------+
结果应为
Time: 2014-01-01 00:00
+------+-------+------+---+
| App1 | Feat1 | Div1 | 4 |
| App1 | Feat1 | Div2 | 2 |
| App1 | Feat2 | Div2 | 1 |
+------+-------+------+---+
这是我到目前为止的代码:(有些是从Stack Overflow上的其他帖子中拼凑出来的)
var results = context.ViewData
.Where(x => (x.FeatureID == 1) &&
StartTimeInput <= x.RecordedDateTime &&
EndTimeInput >= x.RecordedDateTime)
.GroupBy(x => new
{
Application = x.ApplicationName,
Feature = x.FeatureName,
Division = x.Division,
RecordedDateTime = x.RecordedDateTime
})
.Select(x => new
{
Application = x.Key.Application,
Feature = x.Key.Feature,
Division = x.Key.Division,
RecordedDateTime = x.Key.RecordedDateTime,
Count = x.Count()
})
.OrderBy(x => x.RecordedDateTime)
.AsEnumerable().GroupBy(x =>
{
var stamp = x.RecordedDateTime;
stamp = stamp.AddMinutes(-(stamp.Minute % 60));
return stamp;
}).Select(x => new
{
Stamp = x.Key,
Data = x .Select(y => new
{
Application = y.Application,
Feature = y.Feature,
Division = y.Division,
Count = y.Count
})
});
上面的代码让我更接近,但它并没有为我提供应用,功能和部门每小时最大值。
为了澄清,我遇到的麻烦是按小组在60分钟的特定时间点找到一个计数的最大值。
按样本数据对RecordedTime,Application,Feature,Division进行分组会得到以下结果:
+------+-------+------+---+------------------+
| App1 | Feat1 | Div1 | 4 | 2014-01-01 00:00 |
| App1 | Feat1 | Div2 | 1 | 2014-01-01 00:00 |
| App1 | Feat1 | Div1 | 1 | 2014-01-01 00:05 |
| App1 | Feat1 | Div2 | 2 | 2014-01-01 00:05 |
| App1 | Feat2 | Div2 | 1 | 2014-01-01 00:10 |
+------+-------+------+---+------------------+
Between the time range 2014-01-01 00:00 and 2014-01-01 01:00,
the marked lines should be selected as the maximum value for that time range
if you assume that between that time range, none of the grouping exceed that value:
+------+-------+------+---+------------------+
-->| App1 | Feat1 | Div1 | 4 | 2014-01-01 00:00 |<--
| App1 | Feat1 | Div2 | 1 | 2014-01-01 00:00 |
| App1 | Feat1 | Div1 | 1 | 2014-01-01 00:05 |
-->| App1 | Feat1 | Div2 | 2 | 2014-01-01 00:05 |<--
-->| App1 | Feat2 | Div2 | 1 | 2014-01-01 00:10 |<--
+------+-------+------+---+------------------+
如果样本数据是这样的:
+-------------+---------+----------+------------------+
| Application | Feature | Division | RecordedTime |
+-------------+---------+----------+------------------+
| App1 | Feat1 | Div1 | 2014-01-01 00:00 |
| App1 | Feat1 | Div1 | 2014-01-01 00:00 |
| App1 | Feat1 | Div1 | 2014-01-01 00:00 |
| App1 | Feat1 | Div1 | 2014-01-01 00:00 |
| App1 | Feat1 | Div2 | 2014-01-01 00:00 |
| App1 | Feat1 | Div1 | 2014-01-01 00:05 |
| App1 | Feat1 | Div2 | 2014-01-01 00:05 |
| App1 | Feat1 | Div2 | 2014-01-01 00:05 |
| App1 | Feat2 | Div2 | 2014-01-01 00:10 |
.......................................................
| App1 | Feat1 | Div1 | 2014-01-01 00:40 |
| App1 | Feat1 | Div1 | 2014-01-01 00:40 |
| App1 | Feat1 | Div1 | 2014-01-01 00:40 |
| App1 | Feat1 | Div1 | 2014-01-01 00:40 |
| App1 | Feat1 | Div1 | 2014-01-01 00:40 |
| App1 | Feat1 | Div1 | 2014-01-01 00:40 |
| App1 | Feat1 | Div1 | 2014-01-01 00:40 |
| App1 | Feat2 | Div2 | 2014-01-01 00:40 |
| App1 | Feat2 | Div2 | 2014-01-01 00:40 |
| App1 | Feat2 | Div2 | 2014-01-01 00:40 |
| App1 | Feat2 | Div2 | 2014-01-01 00:40 |
| App1 | Feat2 | Div2 | 2014-01-01 00:40 |
+-------------+---------+----------+------------------+
The grouping and results would look like this:
+------+-------+------+---+------------------+
| App1 | Feat1 | Div1 | 4 | 2014-01-01 00:00 |
| App1 | Feat1 | Div2 | 1 | 2014-01-01 00:00 |
| App1 | Feat1 | Div1 | 1 | 2014-01-01 00:05 |
| App1 | Feat1 | Div2 | 2 | 2014-01-01 00:05 |
-->| App1 | Feat2 | Div2 | 1 | 2014-01-01 00:10 |<--
-->| App1 | Feat1 | Div1 | 7 | 2014-01-01 00:40 |<--
-->| App1 | Feat2 | Div2 | 5 | 2014-01-01 00:40 |<--
+------+-------+------+---+------------------+
不同之处在于,在2014-01-01 00:00和01:00之间的60分钟内,来自1区的另外3人在00:40开始使用应用1的功能1,因此最大许可证数量在申请1的特征1的00:00和01:00之间使用变为7。相同的逻辑适用于Feature 2和Division 2,最大值为5。
希望这有帮助!这就是为什么我长期以来一直在努力解决这个问题,这甚至都不是一个容易解释的问题。
答案 0 :(得分:0)
您可以在单个查询中执行此操作。如果您更喜欢方法语法,请告诉我,我可以为您翻译。
var query = from x in context.ViewData
where x.FeatureID == 1
where StartTimeInput <= x.RecordedDateTime
where EndTimeInput >= x.RecordedDateTime
group x by new { x.ApplicationName, x.FeatureName, x.Division } into x
select new
{
Application = x.Key.ApplicationName,
Feature = x.Key.FeatureName,
Division = x.Key.Division,
Max = (from g in x
group g by g.RecordedDateTime into g
orderby g.Count() descending
select g.Count()).FirstOrDefault()
};
如果您还想要时间,请将子查询移动到这样的let
:
...
let max = (from g in x
group g by g.RecordedDateTime into g
orderby g.Count() descending
select g).FirstOrDefault()
select new
{
...
Max = max.Count(),
DateTime = max.Key
};