Search code examples
gogo-gorm

How to handle multiple queries in gorm


I am trying to handle nested queries using gorm and I am having troudble figuring this out.

The queries:

SELECT smId AS 'slimeId', slStatus, slPPIV, slHighRiskSituation, 
(SELECT count(rnIg) FROM ruins WHERE rnSquidStatus = 'Holding on'
AND rnSmId = smId) AS 'holdingOn',
(SELECT count(rnIg) FROM ruins WHERE rnSquidStatus = 'In system' AND rnSmId = smId)
 AS 'inSystem', smSuspectedCorona,
IF(smStatusClosed != 0, 1, 0) as statusClosed, smSurge, 
(SELECT GROUP_CONCAT(rnName) FROM ruins WHERE rnSquidStatus = 'Holding on' AND rnSmId = smId) 
as 'ruinsOnHold',
(SELECT GROUP_CONCAT(rnName) FROM ruins WHERE rnSquidStatus = 'In system' AND rnSmId = smId)
as 'ruinsInSystem' FROM slimes WHERE slId != 0  GROUP BY slId HAVING slId > 0

So I can get some of it done which is pretty basics, the problem is when nesting comes which I don't know what to do in that case

var data []SlimeResponse
db := service.gormdb
db = db.Select("smId as slimeId", "slStatus", "slPPIV", "slHighRiskSituation")
db = db.Where("smId != ?", 0).Group("smId ").Having("smId > ?", 0)
db = db.Table("slimes").Find(&data)

Tried using Where method but didn't work same as Joins but couldn't get it to work


Solution

  • You can use subQuery

    var data []SlimeResponse
    db := service.gormdb
    subQueryHoldingOn := db.
      Select("count(rnIg)").
      Where("rnSquidStatus = 'In system' AND rnSmId = ?", smId).
      Table("ruins")
    subQueryInSystem := db.
      Select("count(rnIg)").
      Where("rnSquidStatus = 'Holding on' AND rnSmId = ?", smId).
      Table("ruins")
    groupSubQueryHoldingOn := db.
      Select("GROUP_CONCAT(rnIg)").
      Where("rnSquidStatus = 'In system' AND rnSmId = ?", smId).
      Table("ruins")
    groupSubQueryInSystem := db.
      Select("GROUP_CONCAT(rnIg)").
      Where("rnSquidStatus = 'Holding on' AND rnSmId = ?", smId).
      Table("ruins")
    db = db.Select("smId as slimeId, slStatus, slPPIV, slHighRiskSituation, (?) as holdingOn, (?) as inSystem, smSuspectedCorona, IF(smStatusClosed != 0, 1, 0) as statusClosed, smSurge, (?) as ruinsOnHold, (?) as ruinsInSystem", subQueryHoldingOn, subQueryInSystem, groupSubQueryHoldingOn, groupSubQueryInSystem)
    db = db.Where("smId != ?", 0).Group("smId ").Having("smId > ?", 0)
    db = db.Table("slimes").Find(&data)
    

    Or

    You can directly pass the select part in Select

    var data []SlimeResponse
    db := service.gormdb
    db = db.Select(
      `
        smId AS 'slimeId',
        slStatus,
        slPPIV,
        slHighRiskSituation, 
        (
          SELECT count(rnIg) FROM ruins WHERE rnSquidStatus = 'Holding on' AND rnSmId = ?
        ) AS 'holdingOn',
        (
          SELECT count(rnIg) FROM ruins WHERE rnSquidStatus = 'In system' AND rnSmId = ?
        ) AS 'inSystem',
        smSuspectedCorona,
        IF(smStatusClosed != 0, 1, 0) as statusClosed,
        smSurge, 
        (
          SELECT GROUP_CONCAT(rnName) FROM ruins WHERE rnSquidStatus = 'Holding on' AND rnSmId = ?
        ) as 'ruinsOnHold',
        (
          SELECT GROUP_CONCAT(rnName) FROM ruins WHERE rnSquidStatus = 'In system' AND rnSmId = ?
        ) as 'ruinsInSystem'
      `, smId, smId, smId, smId
    )
    db = db.Where("smId != ?", 0).Group("smId ").Having("smId > ?", 0)
    db = db.Table("slimes").Find(&data)