如何在子组上使用 GroupBy
How to use GroupBy on a sub Group
也许我做错了,我是 Linq 的新手,但如果有人能帮助我,我将不胜感激。下面是我的代码。我正在尝试对 header 和详细信息 table 中的信息进行一些总结。所以我可以看到每个商家位置的总销售额和总访问次数(个人交易)。详情 table 会将 header table 中的 1 笔交易分成多行,因此 1 笔交易 ID 可以在详情 table.
中出现多次
var query2 = db.sales_transaction_header
.Join(db.sales_transaction_detail,
sth => sth.transaction_id,
std => std.transaction_id,
(sth, std) => new { TransHeader = sth, TransDetail = std })
.GroupBy(x => x.TransHeader.merchant_location_id)
.Select(g => new MerchantConsumerSalesDTO
{
TotalSales = g.Sum(x => x.TransDetail.transaction_amount),
MerchantId = g.FirstOrDefault().TransHeader.merchant_location_id,
TotalVisits = g.GroupBy(x => x.TransHeader.transaction_id).Select(g2 => g2.Count()),
})
.ToList();
TotalVisits 给我带来了各种各样的问题!我原来试过
TotalVisits = g.Select(x => x.TransHeader.transaction_id).Distinct().Count()
但这给了我莫名其妙的错误:
Unknown column 'Project3.merchant_location_id' in 'where clause'
如果没有 .Distinct(),它 returns Count() 是正确的,除了它是错误的数字!因为我只需要计算不同的值,但是使用 Distinct() 它会给我一个错误!所以我尝试在子组上使用 GroupBy。这甚至不允许我编译。我收到各种错误,例如 "cannot implicitly convert Ienumerable to int" 或 "Cannot convert anonymous type to int" - 我束手无策!我是完全走错了路还是这是一个很小很容易解决的问题??
提前致谢!
编辑:
也许这将有助于阐明我的意图。下面列出了我的 table 结构:
sales_transaction_header
transaction_id
merchant_location_id
card
transaction_date
sales_transaction_detail
transaction_detail_id
transaction_id
transaction_amount
seat_nbr
因此,基本上可以根据 seat_nbr 将单个交易分解为多个明细行。因此,如果我理解正确的话,第一个 groupby 应该只对商家 ID 进行分组,仍然为单个交易保留多行。我需要另一个组来计算唯一的交易 ID。正确吗?
此外,我生成的查询如下:
SELECT `Project2`.`merchant_location_id`,
`Project2`.`c1`,
`Project2`.`merchant_location_id1`,
(SELECT Count(1) AS `A1`
FROM (SELECT DISTINCT `Extent7`.`transaction_id`
FROM `sales_transaction_header` AS `Extent7`
INNER JOIN `sales_transaction_detail` AS `Extent8`
ON `Extent7`.`transaction_id` =
`Extent8`.`transaction_id`
WHERE `Project2`.`merchant_location_id` =
`Extent7`.`merchant_location_id`) AS
`Distinct2`) AS `C2`
FROM (SELECT `Apply1`.`merchant_location_id`,
`Apply1`.`merchant_location_id`
AS `merchant_location_id1`,
(SELECT Sum(`Extent6`.`transaction_amount`) AS `A1`
FROM `sales_transaction_header` AS `Extent5`
INNER JOIN `sales_transaction_detail` AS `Extent6`
ON `Extent5`.`transaction_id` =
`Extent6`.`transaction_id`
WHERE `Apply1`.`merchant_location_id` =
`Extent5`.`merchant_location_id`) AS
`C1`
FROM (SELECT `Distinct1`.`merchant_location_id`,
(SELECT `Extent3`.`transaction_id`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `transaction_id`,
(SELECT `Extent3`.`merchant_location_id`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `MERCHANT_LOCATION_ID1`,
(SELECT `Extent3`.`transaction_date`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `transaction_date`,
(SELECT `Extent3`.`post_date`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `post_date`,
(SELECT `Extent3`.`card_token`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `card_token`,
(SELECT `Extent3`.`transaction_type`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `transaction_type`,
(SELECT `Extent3`.`processed`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `processed`,
(SELECT `Extent3`.`partner_transaction_id`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `partner_transaction_id`,
(SELECT `Extent4`.`transaction_detail_id`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `transaction_detail_id`,
(SELECT `Extent4`.`transaction_id` AS `TRANSACTION_ID1`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `TRANSACTION_ID1`,
(SELECT `Extent4`.`transaction_amount`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `transaction_amount`,
(SELECT `Extent4`.`charity_location_id`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `charity_location_id`,
(SELECT `Extent4`.`event_type_id`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `event_type_id`
FROM (SELECT DISTINCT `Extent1`.`merchant_location_id`
FROM `sales_transaction_header` AS `Extent1`
INNER JOIN `sales_transaction_detail` AS
`Extent2`
ON `Extent1`.`transaction_id` =
`Extent2`.`transaction_id`) AS
`Distinct1`) AS `Apply1`) AS `Project2`
更新:
最终,我选择了:
var query = db.sales_transaction_header
.Join(db.sales_transaction_detail,
sth => sth.transaction_id,
std => std.transaction_id,
(sth, std) => new { TransHeader = sth, TransDetail = std })
.GroupBy(x => x.TransHeader.merchant_location_id)
.ToList()
.Select(g => new MerchantConsumerSalesDTO
{
TotalSales = g.Sum(x => x.TransDetail.transaction_amount),
MerchantId = g.Key,
TotalConsumerVisits = g.GroupBy(x => x.TransHeader.transaction_id).Count(),
});
这是由于我使用的 MySql 数据库的限制 - 它在 MSSQL 中工作得很好,显然不需要使用 ToList(),但至少它现在可以工作了!非常感谢,ROB!
在 chat 中进行讨论后,发现该行为是由于 MySql 连接器中的错误所致。
以下代码通过评估内存中的组来绕过此错误:
var query = db.sales_transaction_header
.Join(db.sales_transaction_detail,
sth => sth.transaction_id,
std => std.transaction_id,
(sth, std) => new {TransHeader = sth, TransDetail = std})
.GroupBy(x => x.TransHeader.merchant_location_id)
.ToList()
.Select(g => new MerchantConsumerSalesDTO
{
TotalSales = g.Sum(x => x.TransDetail.transaction_amount),
MerchantId = g.Key,
TotalConsumerVisits = g.GroupBy(x => x.TransHeader.transaction_id).Count(),
});
这是因为它生成了以下代码:
SELECT `GroupBy1`.`k1` AS `merchant_location_id`,
`GroupBy1`.`a1` AS `C1`,
(SELECT Count(1) AS `A1`
FROM (SELECT DISTINCT `Extent3`.`transaction_id`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS `Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `GroupBy1`.`k1` = `Extent3`.`merchant_location_id`) AS
`Distinct1`) AS `C2`
FROM (SELECT `Extent1`.`merchant_location_id` AS `K1`,
Sum(`Extent2`.`transaction_amount`) AS `A1`
FROM `sales_transaction_header` AS `Extent1`
INNER JOIN `sales_transaction_detail` AS `Extent2`
ON `Extent1`.`transaction_id` =
`Extent2`.`transaction_id`
GROUP BY `Extent1`.`merchant_location_id`) AS `GroupBy1`
在MySql中,内部selects不能引用外部结果,所以这一行:
`GroupBy1`.`k1` = `Extent3`.`merchant_location_id`
失败,因为 GroupBy1
超出了 select 的范围。
修复方法是在组后添加 ToList()
,以便最终的 select(和求和)在内存中完成
也许我做错了,我是 Linq 的新手,但如果有人能帮助我,我将不胜感激。下面是我的代码。我正在尝试对 header 和详细信息 table 中的信息进行一些总结。所以我可以看到每个商家位置的总销售额和总访问次数(个人交易)。详情 table 会将 header table 中的 1 笔交易分成多行,因此 1 笔交易 ID 可以在详情 table.
中出现多次 var query2 = db.sales_transaction_header
.Join(db.sales_transaction_detail,
sth => sth.transaction_id,
std => std.transaction_id,
(sth, std) => new { TransHeader = sth, TransDetail = std })
.GroupBy(x => x.TransHeader.merchant_location_id)
.Select(g => new MerchantConsumerSalesDTO
{
TotalSales = g.Sum(x => x.TransDetail.transaction_amount),
MerchantId = g.FirstOrDefault().TransHeader.merchant_location_id,
TotalVisits = g.GroupBy(x => x.TransHeader.transaction_id).Select(g2 => g2.Count()),
})
.ToList();
TotalVisits 给我带来了各种各样的问题!我原来试过
TotalVisits = g.Select(x => x.TransHeader.transaction_id).Distinct().Count()
但这给了我莫名其妙的错误:
Unknown column 'Project3.merchant_location_id' in 'where clause'
如果没有 .Distinct(),它 returns Count() 是正确的,除了它是错误的数字!因为我只需要计算不同的值,但是使用 Distinct() 它会给我一个错误!所以我尝试在子组上使用 GroupBy。这甚至不允许我编译。我收到各种错误,例如 "cannot implicitly convert Ienumerable to int" 或 "Cannot convert anonymous type to int" - 我束手无策!我是完全走错了路还是这是一个很小很容易解决的问题??
提前致谢!
编辑: 也许这将有助于阐明我的意图。下面列出了我的 table 结构:
sales_transaction_header
transaction_id
merchant_location_id
card
transaction_date
sales_transaction_detail
transaction_detail_id
transaction_id
transaction_amount
seat_nbr
因此,基本上可以根据 seat_nbr 将单个交易分解为多个明细行。因此,如果我理解正确的话,第一个 groupby 应该只对商家 ID 进行分组,仍然为单个交易保留多行。我需要另一个组来计算唯一的交易 ID。正确吗?
此外,我生成的查询如下:
SELECT `Project2`.`merchant_location_id`,
`Project2`.`c1`,
`Project2`.`merchant_location_id1`,
(SELECT Count(1) AS `A1`
FROM (SELECT DISTINCT `Extent7`.`transaction_id`
FROM `sales_transaction_header` AS `Extent7`
INNER JOIN `sales_transaction_detail` AS `Extent8`
ON `Extent7`.`transaction_id` =
`Extent8`.`transaction_id`
WHERE `Project2`.`merchant_location_id` =
`Extent7`.`merchant_location_id`) AS
`Distinct2`) AS `C2`
FROM (SELECT `Apply1`.`merchant_location_id`,
`Apply1`.`merchant_location_id`
AS `merchant_location_id1`,
(SELECT Sum(`Extent6`.`transaction_amount`) AS `A1`
FROM `sales_transaction_header` AS `Extent5`
INNER JOIN `sales_transaction_detail` AS `Extent6`
ON `Extent5`.`transaction_id` =
`Extent6`.`transaction_id`
WHERE `Apply1`.`merchant_location_id` =
`Extent5`.`merchant_location_id`) AS
`C1`
FROM (SELECT `Distinct1`.`merchant_location_id`,
(SELECT `Extent3`.`transaction_id`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `transaction_id`,
(SELECT `Extent3`.`merchant_location_id`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `MERCHANT_LOCATION_ID1`,
(SELECT `Extent3`.`transaction_date`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `transaction_date`,
(SELECT `Extent3`.`post_date`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `post_date`,
(SELECT `Extent3`.`card_token`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `card_token`,
(SELECT `Extent3`.`transaction_type`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `transaction_type`,
(SELECT `Extent3`.`processed`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `processed`,
(SELECT `Extent3`.`partner_transaction_id`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `partner_transaction_id`,
(SELECT `Extent4`.`transaction_detail_id`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `transaction_detail_id`,
(SELECT `Extent4`.`transaction_id` AS `TRANSACTION_ID1`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `TRANSACTION_ID1`,
(SELECT `Extent4`.`transaction_amount`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `transaction_amount`,
(SELECT `Extent4`.`charity_location_id`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `charity_location_id`,
(SELECT `Extent4`.`event_type_id`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS
`Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `Distinct1`.`merchant_location_id` =
`Extent3`.`merchant_location_id`
LIMIT 1) AS `event_type_id`
FROM (SELECT DISTINCT `Extent1`.`merchant_location_id`
FROM `sales_transaction_header` AS `Extent1`
INNER JOIN `sales_transaction_detail` AS
`Extent2`
ON `Extent1`.`transaction_id` =
`Extent2`.`transaction_id`) AS
`Distinct1`) AS `Apply1`) AS `Project2`
更新:
最终,我选择了:
var query = db.sales_transaction_header
.Join(db.sales_transaction_detail,
sth => sth.transaction_id,
std => std.transaction_id,
(sth, std) => new { TransHeader = sth, TransDetail = std })
.GroupBy(x => x.TransHeader.merchant_location_id)
.ToList()
.Select(g => new MerchantConsumerSalesDTO
{
TotalSales = g.Sum(x => x.TransDetail.transaction_amount),
MerchantId = g.Key,
TotalConsumerVisits = g.GroupBy(x => x.TransHeader.transaction_id).Count(),
});
这是由于我使用的 MySql 数据库的限制 - 它在 MSSQL 中工作得很好,显然不需要使用 ToList(),但至少它现在可以工作了!非常感谢,ROB!
在 chat 中进行讨论后,发现该行为是由于 MySql 连接器中的错误所致。
以下代码通过评估内存中的组来绕过此错误:
var query = db.sales_transaction_header
.Join(db.sales_transaction_detail,
sth => sth.transaction_id,
std => std.transaction_id,
(sth, std) => new {TransHeader = sth, TransDetail = std})
.GroupBy(x => x.TransHeader.merchant_location_id)
.ToList()
.Select(g => new MerchantConsumerSalesDTO
{
TotalSales = g.Sum(x => x.TransDetail.transaction_amount),
MerchantId = g.Key,
TotalConsumerVisits = g.GroupBy(x => x.TransHeader.transaction_id).Count(),
});
这是因为它生成了以下代码:
SELECT `GroupBy1`.`k1` AS `merchant_location_id`,
`GroupBy1`.`a1` AS `C1`,
(SELECT Count(1) AS `A1`
FROM (SELECT DISTINCT `Extent3`.`transaction_id`
FROM `sales_transaction_header` AS `Extent3`
INNER JOIN `sales_transaction_detail` AS `Extent4`
ON `Extent3`.`transaction_id` =
`Extent4`.`transaction_id`
WHERE `GroupBy1`.`k1` = `Extent3`.`merchant_location_id`) AS
`Distinct1`) AS `C2`
FROM (SELECT `Extent1`.`merchant_location_id` AS `K1`,
Sum(`Extent2`.`transaction_amount`) AS `A1`
FROM `sales_transaction_header` AS `Extent1`
INNER JOIN `sales_transaction_detail` AS `Extent2`
ON `Extent1`.`transaction_id` =
`Extent2`.`transaction_id`
GROUP BY `Extent1`.`merchant_location_id`) AS `GroupBy1`
在MySql中,内部selects不能引用外部结果,所以这一行:
`GroupBy1`.`k1` = `Extent3`.`merchant_location_id`
失败,因为 GroupBy1
超出了 select 的范围。
修复方法是在组后添加 ToList()
,以便最终的 select(和求和)在内存中完成