Having Clause in GORM

Make sure Git is installed on your machine and in your system’s PATH. Install the package to your $GOPATH with the go tool from shell:

$ go get github.com/go-sql-driver/mysql
$ go get -u github.com/jinzhu/gorm




Create a database with the name is learngorm. This database have 1 tables: Product table.

--
-- Table structure for table `product`
--

CREATE TABLE `product` (
  `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(250) NOT NULL,
  `price` double NOT NULL,
  `quantity` int(11) NOT NULL,
  `status` tinyint(1) NOT NULL,
  `created` date DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

--
-- Dumping data for table `product`
--

INSERT INTO `product` (`name`, `price`, `quantity`, `status`, `created`) VALUES
('Tivi 1', 4, 2, 1, '2019-07-10'),
('Tivi 2', 7, 22, 0, '2019-11-08'),
('Mobile 1', 11, 7, 1, '2019-07-11'),
('Mobile 2', 26, 8, 1, '2018-05-04'),
('Computer 1', 8, 2, 0, '2018-07-26');




Create new folder named src. In src folder, create new folder named entities. In entities folder, create new entities as below:

In entities folder, create new go file named product.entity.go as below:

package entities

import (
	"fmt"
	"time"
)

type Product struct {
	Id       int `gorm:"primary_key, AUTO_INCREMENT"`
	Name     string
	Price    float64
	Quantity int
	Status   bool
	Created  time.Time
}

func (product *Product) TableName() string {
	return "product"
}

func (product Product) ToString() string {
	return fmt.Sprintf("id: %d\nname: %s\nprice: %0.1f\nquantity: %d\nstatus: %t\ncreated: %s", product.Id, product.Name, product.Price, product.Quantity, product.Status, product.Created.Format("02/01/2006"))
}

In entities folder, create new go file named productgroup.entity.go as below:

package entities

type ProductGroup struct {
	Status  bool
	Result1 int     // Count Product
	Result2 int     // Sum Quantities
	Result3 float64 // min price
	Result4 float64 // max price
	Result5 float64 // avg price
}

In src folder, create new folder named config. In this folder, create new file named config.go, this file is used to connect mysql database:

package config

import (
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

func GetDB() (*gorm.DB, error) {
	dbDriver := "mysql"
	dbName := "learngorm"
	dbUser := "root"
	dbPassword := "123456"
	db, err := gorm.Open(dbDriver, dbUser+":"+dbPassword+"@/"+dbName+"?charset=utf8&parseTime=True")
	if err != nil {
		return nil, err
	}
	return db, nil
}




In src folder, create new folder named models. In models folder, create new file named product.model.go. This file contains methods to interact with the database.

package models

import (
	"config"
	"entities"
)

type ProductModel struct {
}

func (productModel ProductModel) Having() ([]entities.ProductGroup, error) {
	db, err := config.GetDB()
	if err != nil {
		return nil, err
	} else {
		var productGroups []entities.ProductGroup
		db.Table("product")
			.Select("status, count(id) as result1, sum(quantity) as result2, min(price) as result3, max(price) as result4, avg(price) as result5")
			.Group("status")
			.Having("count(id) > ?", 2)
			.Scan(&productGroups)
		return productGroups, nil
	}
}




In src folder, create new file named main.go as below and use go run main.go command to run program:

package main

import (
	"fmt"
	"models"
)

func main() {
	var productModel models.ProductModel
	productGroups, _ := productModel.Having()
	for _, productGroup := range productGroups {
		fmt.Println("status: ", productGroup.Status)
		fmt.Println("count product: ", productGroup.Result1)
		fmt.Println("sum quantities: ", productGroup.Result2)
		fmt.Println("min price: ", productGroup.Result3)
		fmt.Println("max price: ", productGroup.Result4)
		fmt.Println("avg price: ", productGroup.Result5)
		fmt.Println("--------------------")
	}
}
status:  true
count product:  3
sum quantities:  17
min price:  4
max price:  26
avg price:  13.666666666666666
--------------------