编辑
2024-04-22
还没写好
00
请注意,本文编写于 554 天前,最后修改于 541 天前,其中某些信息可能已经过时。

目录

具体需求
直接查看函数内通过使用GORM动态构建SQL的方法快速完成需求
什么是联表查询
思路方法
筛选问题
石山代码优化
阅读下面这部分代码:
这段代码是不是一个gorm的封装方法
那假如我这个字段ExpectSettleDate在另外一张表里面怎么办?
我说错了,ExpectSettleDate是在twealthorder表里面的,但是BatchId在twealthfund_order表里面
这个as c是干嘛用的?
COUNT(*)是啥意思?
我这里好像只是查出各个值,是不是没必要使用COUNT(*)了
这不就是查询语句吗?
这样,你就能根据特定的条件获取到详细的记录信息。
我是让你修改这段逻辑:
为什么是第一个条件用WHERE来添加,去掉WHERE关键字有影响吗?
那这里的第二段为啥没有where呢?

具体需求

处理范围:公募基金,客户订单管理包括【全部】【待处理】【处理中】【已完成】

筛选项:

  • 搜索条件,新增批次号
  • 新增条件框合单状态:未合单、已合单
  • 日期筛选新增预估结算日

表头:客户订单管理列表新增:批次号、合单状态、预估结算日

不管前端需要什么,我们后端一般来说只管返回我们的json就行了

直接查看函数内通过使用GORM动态构建SQL的方法快速完成需求

什么是联表查询

思路方法

  • 先拿到全部的order id ,然后分个根据order id拿两个表里面的值,一个拿全部,一个拿batchId就行了
  • 定义一个大type内嵌小type,然后两段SQL去查出所有的值赋值到这个type上面来
  • 只查另外一个表里面的batchid,然后拼凑再一个map里面返回就可以了
go
// 先拿到全部的order id ,然后分个根据order id拿两个表里面的值 where :=r.BuildCountRawSQLWithValues() var orderID []string db.raw("select orderId from a join b" + where ).Pluk(&orderID) wealthORder := db.getWealthByOrderIDs(ctx ,orderIDs) fundORder := db.getFundOrderByOrderIDs(ctx ,orderIDs)
go
// 本地测试 var joinModelList []JoinModel var ( sql strings.Builder sqlValues []interface{} whereSet bool ) db.Raw("SELECT wo.*,fo.batchId FROM t_wealth_order wo JOIN t_wealth_fund_order fo ON fo.orderId = wo.id ").Scan(&joinModelList)
go
func (s *wealthAdminService) OrderList(ctx *fiber.Ctx, r *wamapping.OrderListParams) error { var resp wamapping.OrderListResult l := log.FromContext(ctx.UserContext()) // q // 先拿到全部的order id ,然后分个根据order id拿两个表里面的值 // where :=r.BuildCountRawSQLWithValues() // var orderID []string // db.raw("select orderId from a join b" + where ).Pluk(&orderID) // wealthORder := db.getWealthByOrderIDs(ctx ,orderIDs) // fundORder := db.getFundOrderByOrderIDs(ctx ,orderIDs) ms, count, err := s.dbAccess.GetWealthOrderListWithCount(ctx.UserContext(), r) if err != nil { l.Error("query wealth orders failed", zap.String("error", err.Error()), zap.NamedError("errorDetail", err)) return code.Response(ctx, code.NewDefaultError(code.ErrDatabase), nil) } var idList []int for _, v := range ms { idList = append(idList, v.Id) } // 查batch id var fundOrderList []wealth.TWealthFundOrder err = s.dbAccess.Find(ctx.Context(), &fundOrderList, "orderId in (?)", idList) if err != nil { l.Error("query batch ids failed", zap.String("error", err.Error())) return code.Response(ctx, code.NewDefaultError(code.ErrDatabase), nil) } var batchIdMap = make(map[int]string, len(ms)) // 聚合 for _, v := range fundOrderList { batchIdMap[v.OrderId] = v.BatchId } resp.Start = r.Start resp.Count = r.Count resp.Total = count err = copier.CopyWithOption(&resp.List, ms, copier.Option{Converters: []copier.TypeConverter{TimerPoint2StringConverter, String2IntConverter}}) if err != nil { l.Info("copy database model to resp model failed", zap.String("error", err.Error())) return code.Response(ctx, code.NewDefaultError(code.ErrBuildResp), nil) } if len(ms) == 0 { resp.List = []wamapping.OrderListItem{} } // 查找所有的基金代码 productCodeSet := set.NewStringSet() for _, m := range ms { if m.ProductType == orderconstant.W_PRODUCT_TYPE_PRI_FUND || m.ProductType == orderconstant.W_PRODUCT_TYPE_PUB_FUND || m.ProductType == orderconstant.W_PRODUCT_TYPE_ECASH { productCodeSet.Add(m.ProductCode) } } // 查找所有基金产品的份额位数 fundProduct, err := s.MKTWealthClient.GetProductBasicInfoList(ctx.UserContext(), mmapping.ProductBasicInfoListParams{ ProductCodeList: productCodeSet.List(), }) if err != nil { l.Error("query fund products failed", zap.Error(err)) return code.Response(ctx, code.NewDefaultError(code.ErrFundRequestQuotation), nil) } quantityPrecisions := GetProductQuantityPrecisionGroupByProductCode(fundProduct) // 债券和票据没有份额 // 需要考虑到有可能有些基金没有补充产品信息则采用默认的份额精度 for _, m := range ms { if m.ProductType == orderconstant.W_PRODUCT_TYPE_PRI_FUND || m.ProductType == orderconstant.W_PRODUCT_TYPE_PUB_FUND || m.ProductType == orderconstant.W_PRODUCT_TYPE_ECASH { _, exists := quantityPrecisions[m.ProductCode] if exists { continue } quantityPrecisions[m.ProductCode] = orderconstant.DefaultQuantityPrecision } } err = resp.Fix(quantityPrecisions) if err != nil { l.Info("fix resp model failed", zap.String("error", err.Error())) return code.Response(ctx, code.NewDefaultError(code.ErrBuildResp), nil) } err = resp.FillTransactionAmount() if err != nil { l.Info("fill transaction amount to resp model failed", zap.String("error", err.Error())) return code.Response(ctx, code.NewDefaultError(code.ErrBuildResp), nil) } // 如果是公募和星财宝的客户订单有集合订单的 id 信息,需要查询对应的 order number // filter nomineeOrder ID set nomineeOrderIdMap := map[int]struct{}{} var nomineeOrderIds []int for _, m := range ms { if m.NomineeOrderId == 0 { continue } if _, exists := nomineeOrderIdMap[m.NomineeOrderId]; !exists { nomineeOrderIdMap[m.NomineeOrderId] = struct{}{} nomineeOrderIds = append(nomineeOrderIds, m.NomineeOrderId) } } if len(nomineeOrderIds) == 0 { return code.Response(ctx, nil, resp) } // get nominee orders nomineeOrders, err := s.dbAccess.GetWealthNomineeOrdersById(ctx.UserContext(), nomineeOrderIds...) if err != nil { l.Error("query wealth nominee orders failed", zap.String("error", err.Error()), zap.NamedError("errorDetail", err)) return code.Response(ctx, code.NewDefaultError(code.ErrDatabase), nil) } // mapper nominee id with number nomineeOrderIdNumberMap := map[int]string{} for _, m := range nomineeOrders { nomineeOrderIdNumberMap[m.Id] = m.OrderNumber } // fill nominee order number for i, m := range resp.List { if number, exists := nomineeOrderIdNumberMap[m.NomineeOrderId]; exists { resp.List[i].NomineeOrderNumber = number } if _, ok := batchIdMap[m.Id]; ok { resp.List[i].BatchId = batchIdMap[m.Id] } } return code.Response(ctx, nil, resp) }

筛选问题

现在根据字段筛选不到另外一个表,

go
func (params OrderListParams) BuildWhereRawSQLWithValues() (string, []interface{}) { var ( sql strings.Builder sqlValues []interface{} whereSet bool ) // if params.BatchId != "" { // sql.WriteString("SELECT wo.*,fo.batchId FROM t_wealth_order wo JOIN t_wealth_fund_order fo ON fo.orderId = wo.id") // } if params.ProductType != 0 { if whereSet { sql.WriteString(" and productType = ?") } else { sql.WriteString(" productType = ?") } whereSet = true sqlValues = append(sqlValues, params.ProductType) } if params.ProductTypes != "" { productTypes := strings.Split(params.ProductTypes, ",") if whereSet { sql.WriteString(" and productType in(?") } else { sql.WriteString(" productType in(?") } whereSet = true sqlValues = append(sqlValues, productTypes[0]) if len(productTypes) > 1 { for _, productType := range productTypes[1:] { sql.WriteString(",?") sqlValues = append(sqlValues, productType) } } sql.WriteString(")") } // 日期需要包含结束,所以需要加一天 if params.FromSubmitDate != "" && params.ToSubmitDate != "" { if whereSet { sql.WriteString(" and submitTime between ? and DATE_ADD(?,INTERVAL 1 DAY)") } else { sql.WriteString(" submitTime between ? and DATE_ADD(?,INTERVAL 1 DAY)") } whereSet = true sqlValues = append(sqlValues, params.FromSubmitDate, params.ToSubmitDate) } // 日期需要包含结束,所以需要加一天 if params.FromPlaceDate != "" && params.ToPlaceDate != "" { if whereSet { sql.WriteString(" and placeTime between ? and DATE_ADD(?,INTERVAL 1 DAY)") } else { sql.WriteString(" placeTime between ? and DATE_ADD(?,INTERVAL 1 DAY)") } whereSet = true sqlValues = append(sqlValues, params.FromPlaceDate, params.ToPlaceDate) } // 日期需要包含结束,所以需要加一天 if params.FromExportDate != "" && params.ToExportDate != "" { if whereSet { sql.WriteString(" and exportTime between ? and DATE_ADD(?,INTERVAL 1 DAY)") } else { sql.WriteString(" exportTime between ? and DATE_ADD(?,INTERVAL 1 DAY)") } whereSet = true sqlValues = append(sqlValues, params.FromExportDate, params.ToExportDate) } // 日期需要包含结束,所以需要加一天 if params.FromCustodianAcceptDate != "" && params.ToCustodianAcceptDate != "" { if whereSet { sql.WriteString(" and custodianAcceptTime between ? and DATE_ADD(?,INTERVAL 1 DAY)") } else { sql.WriteString(" custodianAcceptTime between ? and DATE_ADD(?,INTERVAL 1 DAY)") } whereSet = true sqlValues = append(sqlValues, params.FromCustodianAcceptDate, params.ToCustodianAcceptDate) } // 日期需要包含结束,所以需要加一天 if params.FromAcceptDate != "" && params.ToAcceptDate != "" { if whereSet { sql.WriteString(" and acceptTime between ? and DATE_ADD(?,INTERVAL 1 DAY)") } else { sql.WriteString(" acceptTime between ? and DATE_ADD(?,INTERVAL 1 DAY)") } whereSet = true sqlValues = append(sqlValues, params.FromAcceptDate, params.ToAcceptDate) } // 日期需要包含结束,所以需要加一天 if params.FromConfirmDate != "" && params.ToConfirmDate != "" { if whereSet { sql.WriteString(" and confirmTime between ? and DATE_ADD(?,INTERVAL 1 DAY)") } else { sql.WriteString(" confirmTime between ? and DATE_ADD(?,INTERVAL 1 DAY)") } whereSet = true sqlValues = append(sqlValues, params.FromConfirmDate, params.ToConfirmDate) } // 日期需要包含结束,所以需要加一天 if params.FromSettleDate != "" && params.ToSettleDate != "" { if whereSet { sql.WriteString(" and settleDate between ? and DATE_ADD(?,INTERVAL 1 DAY)") } else { sql.WriteString(" settleDate between ? and DATE_ADD(?,INTERVAL 1 DAY)") } whereSet = true sqlValues = append(sqlValues, params.FromSettleDate, params.ToSettleDate) } // 日期需要包含结束,所以需要加一天 if params.FromCompleteDate != "" && params.ToCompleteDate != "" { if whereSet { sql.WriteString(" and completeTime between ? and DATE_ADD(?,INTERVAL 1 DAY)") } else { sql.WriteString(" completeTime between ? and DATE_ADD(?,INTERVAL 1 DAY)") } whereSet = true sqlValues = append(sqlValues, params.FromCompleteDate, params.ToCompleteDate) } if params.SearchKey != 0 { if whereSet { sql.WriteString(" and") } else { sql.WriteString("") } whereSet = true switch params.SearchKey { case 1: sql.WriteString(" orderNumber like ?") case 2: sql.WriteString(" isin like ?") case 3: sql.WriteString(" subAccountId like ?") case 4: sql.WriteString(" clientName like ?") case 5: sql.WriteString(" phone like ?") case 6: sql.WriteString(" productName like ?") case 8: sql.WriteString(" productCode like ?") case 9: sql.WriteString(" batchId like ?") case 10: sql.WriteString(" expectSettleDate like ?") case 11: sql.WriteString(" canConsolidate like ?") } sqlValues = append(sqlValues, "%"+params.SearchValue+"%") } // 新增批次号查询 if params.BatchId != "" { if whereSet { sql.WriteString(" AND fo.batchId = ?") } else { sql.WriteString(" fo.batchId = ?") } whereSet = true sqlValues = append(sqlValues, params.BatchId) } // 新增预估结算日查询 if params.ExpectSettleDate != "" { if whereSet { sql.WriteString(" AND expectSettleDate = ?") } else { sql.WriteString(" expectSettleDate = ?") } whereSet = true sqlValues = append(sqlValues, params.ExpectSettleDate) } // 新增可合单查询 if params.CanConsolidate != nil { if whereSet { sql.WriteString(" AND canConsolidate = ?") } else { sql.WriteString(" canConsolidate = ?") } whereSet = true sqlValues = append(sqlValues, *params.CanConsolidate) } if params.OrderStatus != 0 { values := []int{params.OrderStatus} // https://www.tapd.cn/60236733/prong/stories/view/1160236733001009739 // 历史已拒绝的PI债券,前端对于返回已拒绝状态(600)统一映射为平台已拒绝(601),如果筛选平台已拒绝(601)后端同时筛选平台已拒绝(601)和已拒绝(600)。 // 由于债券板块需要兼容展示 PI 债券的数据,如果筛查平台已拒绝则同时筛查出已拒绝 if params.OrderStatus == orderconstant.W_ORDER_STATUS_PLATFORM_REJECTED { values = append(values, orderconstant.W_ORDER_STATUS_REJECTED) } if whereSet { sql.WriteString(" and orderStatus in ?") } else { sql.WriteString(" orderStatus in ?") } whereSet = true sqlValues = append(sqlValues, values) } else { var values []int // 获取所有类型的订单 for _, statusList := range orderconstant.WealthOrderCategoryStatusMap { for _, status := range statusList { values = append(values, status) } } if whereSet { sql.WriteString(" and orderStatus in ?") } else { sql.WriteString(" orderStatus in ?") } whereSet = true sqlValues = append(sqlValues, values) } if params.OrderCategory != 0 { if whereSet { sql.WriteString(" and orderStatus in ?") } else { sql.WriteString(" orderStatus in ?") } whereSet = true sqlValues = append(sqlValues, orderconstant.GetWealthOrderStatusByCategory(params.OrderCategory)) } if params.OrderDirection != 0 { if whereSet { sql.WriteString(" and direction = ?") } else { sql.WriteString(" direction = ?") } whereSet = true sqlValues = append(sqlValues, params.OrderDirection) } if params.Currency != "" { if whereSet { sql.WriteString(" and currency = ?") } else { sql.WriteString(" currency = ?") } whereSet = true sqlValues = append(sqlValues, params.Currency) } if params.NomineeOrderId != 0 { if whereSet { sql.WriteString(" and nomineeOrderId = ?") } else { sql.WriteString(" nomineeOrderId = ?") } whereSet = true sqlValues = append(sqlValues, params.NomineeOrderId) } if params.SourceType != nil { if whereSet { sql.WriteString(" and sourceType = ?") } else { sql.WriteString(" sourceType = ?") } whereSet = true sqlValues = append(sqlValues, *params.SourceType) } if params.CashStatus != 0 { if whereSet { sql.WriteString(" and cashStatus = ?") } else { sql.WriteString(" cashStatus = ?") } whereSet = true sqlValues = append(sqlValues, params.CashStatus) } if params.QuantityStatus != 0 { if whereSet { sql.WriteString(" and quantityStatus = ?") } else { sql.WriteString(" quantityStatus = ?") } whereSet = true sqlValues = append(sqlValues, params.QuantityStatus) } if params.BondType != nil { if whereSet { sql.WriteString(" and bondType = ?") } else { sql.WriteString(" bondType = ?") } whereSet = true sqlValues = append(sqlValues, *params.BondType) } if params.BuyType != nil { if whereSet { sql.WriteString(" and buyType = ?") } else { sql.WriteString(" buyType = ?") } whereSet = true sqlValues = append(sqlValues, *params.BuyType) } if params.ApproveStatus != 0 { if whereSet { sql.WriteString(" and approveStatus = ?") } else { sql.WriteString(" approveStatus = ?") } whereSet = true sqlValues = append(sqlValues, params.ApproveStatus) } if params.NoteType != 0 { if whereSet { sql.WriteString(" and noteType = ?") } else { sql.WriteString(" noteType = ?") } whereSet = true sqlValues = append(sqlValues, params.NoteType) } if params.NoteInterestRateType != 0 { if whereSet { sql.WriteString(" and noteInterestRateType = ?") } else { sql.WriteString(" noteInterestRateType = ?") } whereSet = true sqlValues = append(sqlValues, params.NoteInterestRateType) } if params.CustomerAcceptNoteModify != 0 { if whereSet { sql.WriteString(" and customerAcceptNoteModify = ?") } else { sql.WriteString(" customerAcceptNoteModify = ?") } whereSet = true sqlValues = append(sqlValues, params.CustomerAcceptNoteModify) } if params.Channel != 0 { if whereSet { sql.WriteString(" and channel = ?") } else { sql.WriteString(" where channel = ?") } whereSet = true sqlValues = append(sqlValues, params.Channel) } return sql.String(), sqlValues }

石山代码优化

go
BuildWhereRawSQLWithValues(countFlag bool false) { if countFlag { sql = "SELECT COUNT(*) FROM " + tableName } else { sql = "SELECT * FROM " + tableName } conditionList := make([]string, 0) if(parmas.ProductType!=0) { append(xxx) } ... if len(conditionList) > 0 { sql += " WHERE " + strings.Join(conditionList, " AND ") } }

BuildCountRawSQLWithValues BuildWhereRawSQLWithValues

这两个方法应该合并,通过参数控制 select 后面是 count 还是 wo.* ,不然每次筛选条件还要写两遍。写漏了就是 bug。

阅读下面这部分代码:

go
func (params OrderListParams) BuildWhereRawSQLWithValues() (string, []interface{}) { var ( sql strings.Builder sqlValues []interface{} whereSet bool ) sql.WriteString("select count(*) as c from t_wealth_order") if params.SearchKey != 0 { if whereSet { sql.WriteString(" and") } else { sql.WriteString("") } whereSet = true switch params.SearchKey { case 1: sql.WriteString(" orderNumber like ?") case 2: sql.WriteString(" isin like ?") case 3: sql.WriteString(" subAccountId like ?") case 4: sql.WriteString(" clientName like ?") case 5: sql.WriteString(" phone like ?") case 6: sql.WriteString(" productName like ?") case 8: sql.WriteString(" productCode like ?") case 9: sql.WriteString(" BatchId like ?") case 10: sql.WriteString(" 预估结算日 like ?") case 11: sql.WriteString(" orderStatus like ?") } sqlValues = append(sqlValues, "%"+params.SearchValue+"%") } // 新增批次号条件 if params.BatchId != "" { if whereSet { sql.WriteString(" AND batchId = ?") } else { sql.WriteString(" batchId = ?") } whereSet = true sqlValues = append(sqlValues, params.BatchId) } // 新增预估结算日条件 if params.ExpectSettleDate != "" { if whereSet { sql.WriteString(" AND estimatedSettlementDate = ?") } else { sql.WriteString(" estimatedSettlementDate = ?") } whereSet = true sqlValues = append(sqlValues, params.ExpectSettleDate) } return sql.String(), sqlValues }

这段代码是用Go语言编写的,它定义了一个名为BuildWhereRawSQLWithValues的方法。这个方法属于OrderListParams类型,并返回一个字符串和一个接口的切片。

在这个方法中,首先初始化了一个字符串构建器sql,一个接口的切片sqlValues,以及一个布尔值whereSet

然后,它开始构建一个SQL查询语句,基础查询是"select count(*) as c from t_wealth_order"

接着,它检查params.SearchKey的值。如果params.SearchKey不为0,它会根据params.SearchKey的值在SQL查询语句中添加不同的条件。每个条件后面都会添加一个占位符?,这是为了后面填充具体的搜索值。同时,它会将搜索值添加到sqlValues切片中。

然后,它检查params.BatchIdparams.ExpectSettleDate的值。如果这两个值不为空,它会在SQL查询语句中添加对应的条件,并将这两个值添加到sqlValues切片中。

最后,它返回构建好的SQL查询语句和对应的值。

这个方法的主要用途是根据提供的参数构建一个SQL查询语句,用于从t_wealth_order表中获取数据。

这段代码是不是一个gorm的封装方法

这段代码并不是对GORM(Go Object-Relational Mapping)的封装。GORM是一个用于Go语言的对象关系映射库,用于简化数据库操作。而这段代码中并没有使用GORM的特性或方法,而是直接构建了原生的SQL查询语句。

这个BuildWhereRawSQLWithValues方法构建的SQL语句和参数,可能会在后续的数据库操作中使用到,可能是使用了数据库操作库(如database/sql)的原生方法,或者是GORM的RawExec方法来执行原生SQL语句。但是,这段代码本身并不包含对GORM的使用或封装。

那假如我这个字段ExpectSettleDate在另外一张表里面怎么办?

如果ExpectSettleDate字段在另一张表中,你需要使用SQL的联接操作(JOIN)来联接两张表。你可以根据两张表之间的关系选择适当的联接类型,如内联接(INNER JOIN)、左联接(LEFT JOIN)等。

例如,假设ExpectSettleDate在名为t_settlement的表中,且这两张表可以通过BatchId字段关联,你可以修改代码如下:

go
sql.WriteString("select count(*) as c from t_wealth_order") sql.WriteString(" JOIN t_settlement ON t_wealth_order.BatchId = t_settlement.BatchId") // 其他代码... // 新增预估结算日条件 if params.ExpectSettleDate != "" { if whereSet { sql.WriteString(" AND t_settlement.ExpectSettleDate = ?") } else { sql.WriteString(" t_settlement.ExpectSettleDate = ?") } whereSet = true sqlValues = append(sqlValues, params.ExpectSettleDate) }

这样,你就可以在查询中包含来自t_settlement表的ExpectSettleDate字段。请注意,这只是一个示例,实际的表名、字段名和联接条件可能会根据你的数据库结构有所不同。

我说错了,ExpectSettleDate是在t_wealth_order表里面的,但是BatchId在t_wealth_fund_order表里面

如果ExpectSettleDate字段在t_wealth_order表中,而BatchId字段在t_wealth_fund_order表中,并且你需要根据BatchId来联接这两张表,那么你需要在SQL查询中使用JOIN来联接这两张表。假设这两张表之间通过某个共同字段关联,例如orderId或任何其他可以作为连接两张表的关键字段,下面是如何修改你的代码以包含这种情况的示例:

go
sql.WriteString("SELECT count(*) as c FROM t_wealth_order") sql.WriteString(" JOIN t_wealth_fund_order ON t_wealth_order.orderId = t_wealth_fund_order.orderId") // 其他代码... // 新增批次号条件 if params.BatchId != "" { if whereSet { sql.WriteString(" AND t_wealth_fund_order.BatchId = ?") } else { sql.WriteString(" t_wealth_fund_order.BatchId = ?") } whereSet = true sqlValues = append(sqlValues, params.BatchId) } // 新增预估结算日条件 if params.ExpectSettleDate != "" { if whereSet { sql.WriteString(" AND t_wealth_order.ExpectSettleDate = ?") } else { sql.WriteString(" t_wealth_order.ExpectSettleDate = ?") } whereSet = true sqlValues = append(sqlValues, params.ExpectSettleDate) }

请注意,我在JOIN语句中使用了orderId作为联接t_wealth_order表和t_wealth_fund_order表的字段,这是基于假设。你需要根据你的实际数据库设计替换为正确的字段名。这种方式允许你根据t_wealth_fund_order表中的BatchId字段和t_wealth_order表中的其他条件来筛选记录。

这个as c是干嘛用的?

在SQL中,AS关键字是用来重命名一个字段或者表的别名。在你的查询中,AS c是将count(*)的结果重命名为c

当你执行这个查询时,返回的结果集中,你可以通过新的名字c来访问这个计数结果,而不是count(*)。这使得在处理结果时更加方便,尤其是在字段名可能会引起混淆或者字段名过长不便于处理的情况下。

例如,如果你有以下的SQL查询:

sql
SELECT COUNT(*) AS c FROM t_wealth_order;

那么你可以这样来获取这个计数结果:

go
row := db.QueryRow("SELECT COUNT(*) AS c FROM t_wealth_order") var count int err := row.Scan(&count) if err != nil { // handle error } fmt.Println("Count:", count)

在这个例子中,你可以看到我们通过c来获取COUNT(*)的结果,而不是直接使用COUNT(*)。这样使得代码更加清晰,易于理解。

COUNT(*)是啥意思?

COUNT(*)是一个SQL聚合函数,用于计算表中的总行数。它会返回表中满足查询条件的行数。当你使用COUNT(*)时,它不区分列的值,仅仅计算所有行的数量,包括所有含有NULL值的行。

例如,如果你有一个名为employees的表,你想知道这个表总共有多少行(即多少个员工记录),你可以使用如下查询:

sql
SELECT COUNT(*) FROM employees;

这个查询会返回employees表中所有行的总数。

COUNT(*)COUNT(column_name)的区别在于,COUNT(column_name)仅计算指定列中非NULL值的数量,而COUNT(*)计算的是所有行的数量,不考虑列值是否为NULL。

我这里好像只是查出各个值,是不是没必要使用COUNT(*)了

如果你的目标是获取满足特定条件的记录的详细信息,而不是仅仅计算这些记录的数量,那么确实没有必要使用COUNT(*)COUNT(*)主要用于计数,当你需要了解表中满足某些条件的记录总数时使用。

基于你的描述,如果你想查出具体的记录信息,你应该去掉COUNT(*),并且指定你想从表中检索的列名。例如,如果你想从t_wealth_order表中获取订单的详细信息,你可能会写一个类似这样的查询:

sql

sql
SELECT orderNumber, clientName, phone, productName FROM t_wealth_order

然后根据需要添加WHERE子句来过滤记录,以及可能的JOIN操作来从相关联的表中获取额外的信息。

如果你在之前的代码中使用了COUNT(*)来构建一个查询目的是为了计数,现在需要改为获取详细记录,你需要调整代码来移除COUNT(*)部分,并且按照实际需要选择合适的列名来替换*,同时保留任何的过滤条件和联接操作。

例如,如果你之前的代码是这样的:

go

go
sql.WriteString("select count(*) as c from t_wealth_order")

现在需要改为:

go

go
sql.WriteString("SELECT orderNumber, clientName, phone, productName FROM t_wealth_order")

并且继续添加任何的WHERE条件或者JOIN操作来完成你的查询需求。

这不就是查询语句吗?

go
// 新增预估结算日条件 if params.ExpectSettleDate != "" { if whereSet { sql.WriteString(" AND t_wealth_order.ExpectSettleDate = ?") } else { sql.WriteString(" t_wealth_order.ExpectSettleDate = ?") } whereSet = true sqlValues = append(sqlValues, params.ExpectSettleDate)

是的,你完全正确。在你提供的代码段中,你正在构建一个查询语句,特别是在处理ExpectSettleDate这个条件时,你是在动态地添加一个过滤条件到你的查询中。这个过滤条件基于ExpectSettleDate字段,当params.ExpectSettleDate不为空时,这个条件就会被添加到查询中。

这段代码的逻辑是这样的:

  1. 检查params.ExpectSettleDate是否有值。如果没有值,这个条件就不会被添加到查询中。
  2. 如果whereSet已经为真(意味着之前已经添加了至少一个条件),那么就通过AND关键字添加这个条件,以确保它与之前的条件逻辑上是“与”(AND)关系。
  3. 如果whereSet为假(意味着这是第一个被添加的条件),则直接添加条件。在这里似乎有一个小错误,因为在else分支中,你直接添加了条件而没有添加WHERE关键字。通常,第一个条件前应该有WHERE关键字。
  4. 设置whereSet为真,表示已经有至少一个条件被添加到查询中了。
  5. params.ExpectSettleDate的值添加到sqlValues切片中,这个值稍后会被用作查询参数。

如果你的目的是根据特定的条件检索记录,而不仅仅是计数,那么你可能需要调整你的查询语句的开始部分,从SELECT COUNT(*)改为SELECT加上你感兴趣的列名。同时确保在添加第一个条件时,如果whereSet为假,应该先添加WHERE关键字。例如:

go
sql.WriteString("SELECT orderNumber, clientName, phone, productName FROM t_wealth_order") // 接下来是你的条件逻辑...

这样,你就能根据特定的条件获取到详细的记录信息。

现在已经默认是查的t_wealth_order表了,那查批次号的t_wealth_fund_order代码片段怎么写呢? 下面这两句都被删除了

go
sql.WriteString("SELECT count(*) as c FROM t_wealth_order") sql.WriteString(" JOIN t_wealth_fund_order ON t_wealth_order.orderId = t_wealth_fund_order.orderId")

如果你想查询t_wealth_fund_order表中的批次号,你可以使用以下的SQL代码片段:

sql

sql
sql.WriteString("SELECT batchNumber FROM t_wealth_fund_order")

这将返回t_wealth_fund_order表中所有的批次号。

如果你想要连接t_wealth_ordert_wealth_fund_order表,并查询特定的信息,你可以使用以下的SQL代码片段:

sql

sql
sql.WriteString("SELECT * FROM t_wealth_order") sql.WriteString(" JOIN t_wealth_fund_order ON t_wealth_order.orderId = t_wealth_fund_order.orderId")

这将返回两个表中所有匹配的记录。你可以替换*为你需要查询的特定字段。

请注意,你需要确保t_wealth_order.orderIdt_wealth_fund_order.orderId这两个字段在两个表中都存在,并且具有相同的数据类型和数据长度。

我是让你修改这段逻辑:

go
// 新增批次号条件 if params.BatchId != "" { if whereSet { sql.WriteString(" AND t_wealth_fund_order.BatchId = ?") } else { sql.WriteString(" t_wealth_fund_order.BatchId = ?") } whereSet = true sqlValues = append(sqlValues, params.BatchId) }

如果你想要在查询中添加一个基于t_wealth_fund_order表的BatchId字段的条件,你需要确保t_wealth_order表和t_wealth_fund_order表已经通过JOIN语句连接起来。然后,你可以添加一个WHERE子句(如果是第一个条件)或者使用AND(如果已经有其他条件)来添加BatchId的过滤条件。

由于你删除了之前的JOIN语句,我们需要重新添加它,并且确保在添加BatchId条件之前已经有一个JOIN操作。以下是修改后的逻辑:

go

go
// 确保已经加入了JOIN语句连接两个表 sql.WriteString(" FROM t_wealth_order") sql.WriteString(" JOIN t_wealth_fund_order ON t_wealth_order.orderId = t_wealth_fund_order.orderId") // 其他条件... // 新增批次号条件 if params.BatchId != "" { if whereSet { sql.WriteString(" AND t_wealth_fund_order.BatchId = ?") } else { sql.WriteString(" WHERE t_wealth_fund_order.BatchId = ?") // 注意这里使用了WHERE whereSet = true // 表示WHERE子句已经被设置 } sqlValues = append(sqlValues, params.BatchId) }

请注意,在else分支中,我们使用了WHERE关键字而不是直接写入条件,这是因为这是第一个添加到查询中的条件。如果whereSet之前已经被设置为true,则意味着已经有了其他的WHERE条件,所以我们只需要添加AND

最后,我们将params.BatchId的值添加到sqlValues切片中,这个值稍后将用作SQL查询的参数。

sql.WriteString(" JOIN t_wealth_fund_order ON t_wealth_order.id = t_wealth_fund_order.orderId")

如果你想要根据t_wealth_order表的id字段和t_wealth_fund_order表的orderId字段进行表连接,并且添加一个基于t_wealth_fund_order表的BatchId字段的条件,你可以按照以下方式修改你的代码:

go

go
// 加入JOIN语句连接两个表,基于t_wealth_order的id和t_wealth_fund_order的orderId字段 sql.WriteString(" FROM t_wealth_order") sql.WriteString(" JOIN t_wealth_fund_order ON t_wealth_order.id = t_wealth_fund_order.orderId") // 其他条件... // 新增批次号条件 if params.BatchId != "" { if whereSet { // 如果已经有条件存在,使用AND来添加新条件 sql.WriteString(" AND t_wealth_fund_order.BatchId = ?") } else { // 如果是第一个条件,使用WHERE sql.WriteString(" WHERE t_wealth_fund_order.BatchId = ?") whereSet = true // 标记WHERE条件已经被设置 } sqlValues = append(sqlValues, params.BatchId) // 添加BatchId的值到参数列表 }

在这个修改后的代码中,我们首先确保JOIN语句是根据你提供的正确字段进行的(t_wealth_order.idt_wealth_fund_order.orderId)。然后,我们根据是否已经存在其他WHERE条件来决定是直接添加WHERE子句还是使用AND关键字来添加BatchId的条件。

这样,你就能够根据BatchId条件从连接的两个表中检索数据了。确保sqlValues切片中的参数顺序与查询中的占位符?顺序匹配,这样参数才能正确地应用于查询。

为什么是第一个条件用WHERE来添加,去掉WHERE关键字有影响吗?

在SQL查询中,WHERE子句是用来过滤记录的,只有满足条件的记录才会被选中。如果你去掉WHERE关键字,那么你的SQL语句就会缺少一个过滤条件,这样可能会导致选取到不符合你预期的数据。

比如,你有一个学生表,你想选取年龄大于18的学生,你可能会写这样的SQL语句:

sql
SELECT * FROM students WHERE age > 18;

如果你去掉WHERE关键字,那么SQL语句就变成了:

sql
SELECT * FROM students age > 18;

这是一个语法错误的SQL语句,因为在字段列表中,age > 18并不是一个有效的字段表达式。

所以,WHERE关键字在SQL中是非常重要的,它决定了你的查询条件。如果去掉,可能会导致你的查询结果不符合预期,或者查询语句无法执行。

那这里的第二段为啥没有where呢?

go
// 新增预估结算日条件 if params.ExpectSettleDate != "" { if whereSet { sql.WriteString(" AND estimatedSettlementDate = ?") } else { sql.WriteString(" estimatedSettlementDate = ?") } whereSet = true sqlValues = append(sqlValues, params.ExpectSettleDate) }

这段代码是在构建SQL查询语句。在这里,"where"关键字的使用取决于是否已经在SQL语句中添加了一个条件。如果已经添加了一个条件,那么后续的条件就需要用"AND"来连接,而不是"where"。这是因为在SQL中,"where"关键字只能出现一次,用于引入过滤条件,而"AND"则用于添加额外的过滤条件。

在这段代码中,whereSet变量用于跟踪是否已经设置了"where"条件。如果whereSet为true,那么就会添加"AND",否则就会直接添加条件,而不添加"where"。这是因为这段代码可能是查询语句的一部分,"where"可能已经在前面的代码中添加了。

所以,这段代码没有"where",是因为它依赖于外部条件来决定是否需要添加"where"。

本文作者:JIeJaitt

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!