现在呢,我们有一个需求,就是,记录出上班的员工,连续休四天的人员,并将其打印出来。
最开始,我是想从T-SQL角度去解决这个问题,网上也有对应的案例,使用到一些 窗口函数 rank等。
为了更了解go语言的使用,我把这块逻辑放到go中去做处理。自然而然会使用到 gorm。
首先,我们需要创建一张表:
CREATE TABLE `wd_broker_schedule` ( `pid` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', `idcard_num` varchar(32) DEFAULT '' COMMENT '身份证号(不区分大小写)', `server_date` date NOT NULL DEFAULT '0000-00-00' COMMENT '服务日期', `rest_type` tinyint(4) DEFAULT '0' COMMENT '休息类型 0无休 1全天休息 2上午休息 3下午休息', PRIMARY KEY (`pid`) ) ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8mb4;
go代码如下:
package main import ( "fmt" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" "time" ) type WdBrokerSchedule struct { Pid int64 `gorm:"pid" json:"pid"` // 主键 IdcardNum string `gorm:"idcard_num" json:"idcard_num"` // 身份证号(不区分大小写) ServerDate string `gorm:"server_date" json:"server_date"` // 服务日期, 2020-12-12 RestType uint `gorm:"rest_type" json:"rest_type"` // 休息类型 0无休 1全天休息 2上午休息 3下午休息 } var timeTemplates = []string{ "2006-01-02 15:04:05", //常规类型 "2006/01/02 15:04:05", "2006-01-02", "2006/01/02", "15:04:05", } // TimeStringToGoTime 时间格式字符串转换 // 这个地方,不推荐for 循环这样去写,小demo我是为了记录这个写法,这个地方应该按照指定的日期格式去转换 func TimeStringToGoTime(tm string) time.Time { for i := range timeTemplates { t, err := time.ParseInLocation(timeTemplates[i], tm, time.Local) if nil == err && !t.IsZero() { return t } } return time.Time{} } // IsContain 是否包含 func IsContain(items []string, item string) bool { for _, eachItem := range items { if eachItem == item { return true } } return false } func main() { db, err := gorm.Open("mysql", "user:pwd@tcp(ip:3306)/database?charset=utf8") if err != nil { panic("failed to connect database") } defer db.Close() var wds []WdBrokerSchedule db.Table("wd_broker_schedule"). Where("rest_type > ?", 0). Order("server_date desc"). Find(&wds) var timeMap = make(map[string][]string) // key是身份证号码 // 待优化 if true {// 初始化timeMap for i := 0; i < len(wds); i++ { timeMap[wds[i].IdcardNum] = []string{} } for i := 0; i < len(wds); i++ { if _, ok := timeMap[wds[i].IdcardNum]; ok { timeMap[wds[i].IdcardNum] = append(timeMap[wds[i].IdcardNum], wds[i].ServerDate) } } } var ids []string for k, v := range timeMap { if len(v) < 4 { fmt.Println("长度小于4,不符合!") continue } for i := 0; i <= len(v)-4; i++ { if IsContain(ids, k) { break } timeFirst := v[0+i] timeFourth := v[3+i] tempTime := TimeStringToGoTime(timeFirst).AddDate(0, 0, -3).Format("2006-01-02") if timeFourth == tempTime { ids = append(ids, k) } } } fmt.Println("=====================") fmt.Println("最终的人员身份证为:", ids) }
以上代码,还有值得优化的地方,比如,执行sql查询,没有做错误处理,map初始化,可以合并等。。。