SQL Anywhere按不同条件取同列数据及VB.NET统计实现方法
解决方案
你可以选择SQL侧计算或者VB.NET内存侧计算两种方案,优先推荐第一种,性能更高、代码量更小。
方案1:SQL直接统计(推荐)
直接在SQL Anywhere中完成统计计算,VB.NET只需要接收查询结果即可。
查询SQL示例
你可以用分组聚合的方式实现需求,@TargetDate为你要查询的指定日期参数:
SELECT CUSTID AS `Cust id`, @TargetDate AS `date`, MAX(CASE WHEN DDAT = @TargetDate THEN AMOUNT ELSE 0 END) AS `Amount`, SUM(AMOUNT) AS `Total amount` FROM 你的表名称 GROUP BY CUSTID -- 过滤仅保留指定日期有消费记录的客户 HAVING MAX(CASE WHEN DDAT = @TargetDate THEN 1 ELSE 0 END) = 1
VB.NET调用示例
使用参数化查询调用上面的SQL,避免SQL注入和日期格式错误:
Imports System.Data.Odbc ' 配置参数 Dim targetDate As Date = New Date(2021, 4, 4) ' 替换为你要查询的实际日期 Dim connectionString As String = "你的SQL Anywhere数据库连接字符串" Dim resultTable As New DataTable() ' 执行查询 Using conn As New OdbcConnection(connectionString) conn.Open() Dim querySql As String = " SELECT CUSTID AS 'Cust id', ? AS 'date', MAX(CASE WHEN DDAT = ? THEN AMOUNT ELSE 0 END) AS 'Amount', SUM(AMOUNT) AS 'Total amount' FROM 你的表名称 GROUP BY CUSTID HAVING MAX(CASE WHEN DDAT = ? THEN 1 ELSE 0 END) = 1 " Using cmd As New OdbcCommand(querySql, conn) ' ODBC按参数顺序传值 cmd.Parameters.AddWithValue(Nothing, targetDate) cmd.Parameters.AddWithValue(Nothing, targetDate) cmd.Parameters.AddWithValue(Nothing, targetDate) Using adapter As New OdbcDataAdapter(cmd) adapter.Fill(resultTable) End Using End Using End Using ' resultTable 就是你需要的最终统计结果,可以直接绑定到DataGridView等控件使用
方案2:VB.NET内存计算
如果你已经提前拉取了所有原始数据到本地,可以用LINQ在内存中完成统计:
' 假设dtOriginal是已经加载了所有原始数据的DataTable Dim targetDate As Date = New Date(2021, 4, 4) Dim statisticsResult = dtOriginal.AsEnumerable() _ .GroupBy(Function(row) row.Field(Of Integer)("CUSTID")) _ .Where(Function(group) group.Any(Function(row) row.Field(Of Date)("DDAT").Date = targetDate.Date)) _ .Select(Function(group) New With { .CustId = group.Key, .查询日期 = targetDate, .当日金额 = group.First(Function(row) row.Field(Of Date)("DDAT").Date = targetDate.Date).Field(Of Decimal)("AMOUNT"), .累计总金额 = group.Sum(Function(row) row.Field(Of Decimal)("AMOUNT")) }).ToList() ' statisticsResult 就是最终的统计结果
注意事项
- 如果你的
DDAT字段包含时间部分,判断日期相等时需要先截断时间,SQL中用DATE(DDAT),VB中用.Date属性取日期部分 - 所有涉及日期查询的场景都优先用参数化传值,不要直接拼接SQL字符串,避免格式不兼容问题
内容的提问来源于stack exchange,提问作者Rohit Joshi
相关产品推荐
相关产品推荐

