为简洁起见,我简化了场景.
初始数据:
| EngineerId | FirstName | LastName | BirthdateOn | CupsOfCoffee | HoursOfSleep |
| ---------- | --------- | -------- | ----------- | ------------ | ------------ |
| 1 | John | Doe | 1990-01-01 | 5 | 8 |
| 2 | James | Bond | 1990-01-01 | 1 | 6 |
| 3 | Leeroy | Jenkins | 2000-06-20 | 16 | 10 |
| 4 | Jane | Doe | 2000-06-20 | 8 | 2 |
| 5 | Lorem | Ipsum | 2010-12-25 | 4 | 5 |
db.engineers.insertMany([
{ FirstName: 'John', LastName: 'Doe', BirthdateOn: ISODate('1990-01-01'), CupsOfCoffee: 5, HoursOfSleep: 8 },
{ FirstName: 'James', LastName: 'Bond', BirthdateOn: ISODate('1990-01-01'), CupsOfCoffee: 1, HoursOfSleep: 6 },
{ FirstName: 'Leeroy', LastName: 'Jenkins', BirthdateOn: ISODate('2000-06-20'), CupsOfCoffee: 16, HoursOfSleep: 10 },
{ FirstName: 'Jane', LastName: 'Doe', BirthdateOn: ISODate('2000-06-20'), CupsOfCoffee: 8, HoursOfSleep: 2 },
{ FirstName: 'Lorem', LastName: 'Ipsum', BirthdateOn: ISODate('2010-12-25'), CupsOfCoffee: 4, HoursOfSleep: 5 }
])
我们希望看到:
- 工程师喝掉的那杯咖啡
- 按咖啡杯降序排列的行号
- 出生日期相同的工程师的数量
- 有共同生日的工程师喝的咖啡的总和
- 拥有共同生日的工程师的平均睡眠时间
该SQL查询为:
SELECT
FirstName,
LastName,
BirthdateOn,
CupsOfCoffee,
ROW_NUMBER() OVER (PARTITION BY BirthdateOn ORDER BY CupsOfCoffee DESC) AS 'Row Number',
COUNT(EngineerId) OVER (PARTITION BY BirthdateOn) AS TotalEngineers,
SUM(CupsOfCoffee) OVER (PARTITION BY BirthdateOn) AS TotalCupsOfCoffee,
AVG(HoursOfSleep) OVER (PARTITION BY BirthdateOn) AS AvgHoursOfSleep
FROM Engineers
导致以下情况:
| FirstName | LastName | BirthdateOn | Row Number | CupsOfCoffee | TotalEngineers | TotalCupsOfCoffee | AvgHoursOfSleep |
| --------- | -------- | ----------- | ---------- | ------------ | -------------- | ----------------- | --------------- |
| John | Doe | 1990-01-01 | 1 | 5 | 2 | 6 | 7 |
| James | Bond | 1990-01-01 | 2 | 1 | 2 | 6 | 7 |
| Leeroy | Jenkins | 2000-06-20 | 1 | 16 | 2 | 24 | 6 |
| Jane | Doe | 2000-06-20 | 2 | 8 | 2 | 24 | 6 |
| Lorem | Ipsum | 2010-12-25 | 1 | 4 | 1 | 4 | 5 |
我对MongoDB Aggregate管道做了相当多的阅读,但还没有找到一个好的解决方案.我知道这是not个SQL,解决方案可能不会产生这种格式的结果(尽管这将是令人惊讶的).我考虑过的一件事是将聚合和集合的结果组合在一起,但这要么是不可能的,要么是我一直在使用错误的术语进行搜索.$merge
看起来很有希望,但AFAIU它会修改原来的Collection ,这不是好事.
我已经做到了以下几点,但结果不包括"行号"、特定工程师消耗的杯子或工程师的ID和姓名.
db.engineers.aggregate([
{
$group: {
_id: '$BirthdateOn',
TotalEngineers: {
$count: { }
},
TotalCupsOfCoffee: {
$sum: '$CupsOfCoffee'
},
AvgHoursOfSleep: {
$avg: '$HoursOfSleep'
}
}
}
])
我的 idea 是把所有的工程师加到find
个,然后运行汇总,然后按BirthdateOn
"加入"到工程师那里.
谢谢你的帮助!非常感谢.