go 查询连休天数的员工信息

现在呢,我们有一个需求,就是,记录出上班的员工,连续休四天的人员,并将其打印出来。

最开始,我是想从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初始化,可以合并等。。。

posted @ 2021-04-22 19:12  冰乐  阅读(80)  评论(0编辑  收藏  举报