Skip to content
FreeSql 官方文档FreeSql 官方文档
指南
扩展
服务支持
github icon
    • 基于FreeSql扩展
      • 多个 IFreeSql实例,如何注入使用
        • 技巧:ISelect 如何拷贝(copy)复用,克隆(clone)
          • Docker+ FreeSql
            • FreeSql 如何实现审计日志
              • Mysql 5.5 兼容性
                • In多列查询,表达式自定义实现
                  • 技巧:自定义解析表达式树,实现动态聚合列 sum(case when ...)

                  技巧:自定义解析表达式树,实现动态聚合列 sum(case when ...)

                  author iconnicyecalendar icon2022年6月24日timer icon大约 1 分钟word icon约 301 字

                  # 技巧:自定义解析表达式树,实现动态聚合列 sum(case when ...)

                  SELECT
                  a."Time",
                  v1 = sum(case when a."Id" == 1 then 1 else 0 end),
                  v2 = sum(case when a."Id" == 2 then 1 else 0 end),
                  v3 = sum(case when a."Id" == 3 then 1 else 0 end)
                  FROM "table" a
                  WHERE a."Id" IN (1,2,3)
                  GROUP BY a."Time"
                  
                  1
                  2
                  3
                  4
                  5
                  6
                  7
                  8

                  如上 v1,v2,v3 是动态聚合值,如果 where IN (1,2,3,4) 那就会产生 v1-v4

                  正常情况下,静态的 lambda 查询没办法处理这种动态列查询。


                  变通一下,这样查询:

                  SELECT
                  a."Time",
                  v = sum(case when a."Id" == 1 then 1 else 0 end) + ','
                      sum(case when a."Id" == 2 then 1 else 0 end) + ','
                      sum(case when a."Id" == 3 then 1 else 0 end)
                  FROM "table" a
                  WHERE a."Id" IN (1,2,3)
                  GROUP BY a."Time"
                  
                  1
                  2
                  3
                  4
                  5
                  6
                  7
                  8

                  如此便可以使用 FreeSql 实现:

                  var ids = new int[] { 1,2,3 };
                  fsql.Select<table>()
                      .Where(a => ids.Contains(a.Id))
                      .GroupBy(a => a.Time)
                      .ToList(g => new 
                      {
                          Time = g.Key,
                          Values = MyExt.SumCase(ids, g.Value.Id)
                      });
                  
                  1
                  2
                  3
                  4
                  5
                  6
                  7
                  8
                  9

                  自定义解析表达式树,实现如下:

                  [ExpressionCall]
                  public static class MyExt
                  {
                      internal static ThreadLocal<ExpressionCallContext> expContext = new ThreadLocal<ExpressionCallContext>();
                  
                      public static string SumCase<TValue>([RawValue] TValue[] values, TValue column)
                      {
                          var ctx = expContext.Value;
                          ctx.Result = ctx.Utility.CommonUtils.StringConcat(
                              values.Select((val, idx) => 
                                  new [] {
                                      ctx._commonExp._common.IsNull($"SUM(case when {ctx.ParsedContent["column"]} = {ctx.FormatSql(val)} then 1 else 0 end)", 0),
                                      idx == values.Length - 1 ? "''" : "','"
                                  }).SelectMany(a => a).ToArray(), 
                              values.Select(val => 
                                  new[]{
                                      typeof(TValue),
                                      typeof(string)
                                  }).SelectMany(a => a).ToArray());
                          return default;
                      }
                  }
                  
                  1
                  2
                  3
                  4
                  5
                  6
                  7
                  8
                  9
                  10
                  11
                  12
                  13
                  14
                  15
                  16
                  17
                  18
                  19
                  20
                  21
                  22
                  edit icon在 GitHub 上编辑此页open in new window
                  上次编辑于: 2022/8/11 08:57:16
                  贡献者: 2881099,igeekfan
                  上一页
                  In多列查询,表达式自定义实现
                  Copyright © 2018-present nicye
                  Copyright © 2022 nicye

                  该应用可以安装在你的 PC 或移动设备上。这将使该 Web 应用程序外观和行为与其他应用程序相同。它将在出现在应用程序列表中,并可以固定到主屏幕,开始菜单或任务栏。此 Web 应用程序还将能够与其他应用程序和你的操作系统安全地进行交互。

                  详情