0

我有这个正在运行的查询:

SELECT DISTINCT
       b.NAME AS [Service Name],
       CASE
           WHEN [a].[PAY_MODE_ID] IN ( 1, 2 ) THEN
               'OFFLINE'
           ELSE
               'ONLINE'
       END AS [Transaction Type],
       p.NAME AS [Payment Method],
       SUM(a.REQUESTED_QTY) AS [Transaction],
       SUM(a.ITEM_TOTAL) AS Income
FROM dbo.BILL_INFO_DETAIL AS a
    INNER JOIN dbo.SERVICE_INFO AS b
        ON a.SERVICE_CODE = b.SERVICE_CODE
    INNER JOIN dbo.PAY_MODE AS p
        ON a.PAY_MODE_ID = p.PAY_MODE_ID
WHERE (a.INPUT_STATUS = '1')
      AND (b.SERVICE_CODE IN ( 1610, 1611, 1612 ))
      AND (CONVERT(VARCHAR(2), a.STAMP_DATE, 101) IN ( '10', '11', '12' ))
      AND (CONVERT(VARCHAR(4), a.STAMP_DATE, 102) IN ( '2017' ))
      AND (b.FEE > 1)
GROUP BY b.NAME,
         CASE
             WHEN [a].[PAY_MODE_ID] IN ( 1, 2 ) THEN
                 'OFFLINE'
             ELSE
                 'ONLINE'
         END,
         p.NAME
ORDER BY [Transaction Type];

Linqer 无法将其转换为正确的 LINQ:

SQL 语法错误:每个 GROUP BY 表达式必须至少包含一个列引用。

此查询在 SQL Server 中运行。任何指针?

笔记:

  • 删除DISTINCT没有效果
  • 删除ORDER BY没有效果
  • 删除;没有效果
4

2 回答 2

3

用于将 SQL 转换为 LINQ 查询理解:

  1. 将子选择转换FROM为单独声明的变量。
  2. 按 LINQ 子句顺序翻译每个子句,将单子和聚合运算符(、、、DISTINCTTOPMIN翻译MAX成应用于整个 LINQ 查询的函数。
  3. 使用表别名作为范围变量。使用列别名作为匿名类型字段名称。
  4. 对多个列使用匿名类型 ( new {... })。
  5. JOIN不是所有相等性测试的条件AND必须使用where连接之外的子句或叉积 ( from... from...) 处理,然后where
  6. JOIN两个表之间的多个ANDed 相等测试的条件应转换为匿名对象
  7. LEFT JOIN通过使用into joinvariable并从joinvariable执行另一个模拟from,然后..DefaultIfEmpty()
  8. 替换COALESCE为条件运算符 ( ?:) 和null测试。
  9. 转换IN为... .Contains()NOT IN使用常量列表的文字数组或数组变量。!Contains()
  10. 将x BETWEEN AND 转换为 <= x && x <=
  11. 转换CASE为三元条件运算符?:
  12. SELECT *必须替换为 select range_variable 或对于连接,一个包含所有范围变量的匿名对象。
  13. SELECT字段必须替换为select new {...}创建具有所有所需字段或表达式的匿名对象。
  14. 正确的FULL OUTER JOIN必须使用扩展方法来处理。

因此,对于您的查询,

var ans = (from a in dbo.BILL_INFO_DETAIL
           join b in dbo.SERVICE_INFO on a.SERVICE_CODE equals b.SERVICE_CODE
           join p in dbo.PAY_MODE on a.PAY_MODE_ID equals p.PAY_MODE_ID
           where (a.INPUT_STATUS == "1") &&
                 (new[] { 1610, 1611, 1612 }.Contains(b.SERVICE_CODE)) &&
                 (new[] { 10, 11, 12 }.Contains(a.STAMP_DATE.Month)) &&
                 (new[] { 2017 }.Contains(a.STAMP_DATE.Year)) &&
                 (b.FEE > 1)
           let TransactionType = new[] { 1, 2 }.Contains(a.PAY_MODE_ID) ? "OFFLINE" : "ONLINE"
           group new { a, b, p } by new { bName = b.NAME, TransactionType, pName = p.NAME } into abpg
           orderby abpg.Key.TransactionType
           select new {
               Service_Name = abpg.Key.bName,
               TransactionType = abpg.Key.TransactionType,
               Payment_Method = abpg.Key.pName,
               Transaction = abpg.Sum(abp => abp.a.REQUESTED_QTY),
               Income = abpg.Sum(abp => abp.a.ITEM_TOTAL)
           }).Distinct();
于 2018-03-06T19:58:44.873 回答
0

似乎我所要做的就是删除带有 PAY_MODE_ID 的 CASE。除了该更改之外,我还修改了查询,以使其准备好生产:

SELECT si.SERVICE_CODE,     
       si.NAME AS [ServiceName],
       bid.PAY_MODE_ID AS [PaymentId],
       p.NAME AS [PaymentName],
       SUM(bid.REQUESTED_QTY) AS [Transaction],
       SUM(bid.ITEM_TOTAL) AS [Income]
FROM BILL_INFO_DETAIL AS bid
    INNER JOIN dbo.SERVICE_INFO AS si
        ON bid.SERVICE_CODE = si.SERVICE_CODE
    INNER JOIN dbo.PAY_MODE AS p
        ON bid.PAY_MODE_ID = p.PAY_MODE_ID
WHERE (bid.INPUT_STATUS = '1')
      AND (si.SERVICE_CODE IN ( 1610, 1611, 1612 ))
      AND (CONVERT(VARCHAR(2), bid.STAMP_DATE, 101) IN ( '10', '11', '12' ))
      AND (CONVERT(VARCHAR(4), bid.STAMP_DATE, 102) IN ( '2017' ))
      AND (si.FEE > 1)
GROUP BY si.SERVICE_CODE,
         si.NAME,   
         bid.PAY_MODE_ID,
         p.NAME

这导致了 LINQ(稍作修改):

    from bid in db.BILL_INFO_DETAIL
    where
      bid.INPUT_STATUS == true &&
      (new int[] {1610, 1611, 1612 }).Contains(bid.SERVICE_INFO.SERVICE_CODE) &&
      (new int[] {10, 11, 12 }).Contains(bid.STAMP_DATE.Value.Month) &&
      bid.STAMP_DATE.Value.Year == 2017 &&
      bid.SERVICE_INFO.FEE > 1
    group new {bid.SERVICE_INFO, bid, bid.PAY_MODE} by new {
      bid.SERVICE_INFO.SERVICE_CODE,
      bid.SERVICE_INFO.NAME,
      bid.PAY_MODE_ID,
      Column1 = bid.PAY_MODE.NAME
    } into g
    select new {
      g.Key.SERVICE_CODE,
      ServiceName = g.Key.NAME,
      PaymentId = g.Key.PAY_MODE_ID,
      PaymentName = g.Key.NAME,
      Transaction = (int?)g.Sum(p => p.bid.REQUESTED_QTY),
      Income = (decimal?)g.Sum(p => p.bid.ITEM_TOTAL)
    }
于 2018-03-06T19:59:47.283 回答