convert mysql query contains sum and group_concat to mongodb query

回眸只為那壹抹淺笑 提交于 2019-12-12 15:11:43

问题


I would like to convert below mysql query to mongodb query.

SELECT substring(o.schedule_datetime,1,4) 'Year',
SUM(IF(o.order_status in ('SUCCESS','#SUCCESS'),1,0)) 'SUCCESS'
FROM (
      select group_concat(distinct ifnull(os.order_status,'') order by os.order_status 
      separator '#') 'order_status',schedule_datetime
      from order_summary os group by order_number
     )o group by 1 desc;

For Example: I have sample table

id order_number product_number order_status schedule_datetime
1  001          001.1          SUCCESS      20180103
2  001          001.2          SUCCESS      20180102
3  111          111.1          SUCCESS      20171225
4  111          111.2          SUCCESS      20171224
5  222          222.1          INPROGRESS   20171122
6  222          222.2          SUCCESS      20171121

I get the output using above mysql query for order status SUCCESS

Year SUCCESS
2018 1
2017 1

I have used separator(#) to combine multiple statues as string and get the desired result by status, to get INPROGRESS i will be just changing SUM funtion as shown below :

SUM(IF(o.order_status in ('INPROGRESS','INPROGRESS#SUCCESS', '#INPROGRESS','#INPROGRESS#SUCCESS'),1,0)) 'INPROGRESS' 

I have tried to write the mongodb query, but got stuck how to combine sum and if condition as well group_concat with seperator as i used in mysql query.

db.order_summary.aggregate([ 

 { "$project" :
    { "orderDate" : 1 , "subOrderDate" : { "$substr" : [ "$order_date" , 0 , 4]},
        "order_number":"$order_number"
    },

 } ,
 { "$group":{
     "_id": { "order_number" : "$order_number", "Year": "$subOrderDate", "order_status":{"$addToSet":{"$ifNull":["$order_status",'']}}}
    }
 },
 { "$group": {
     "_id": "$_id.Year", "count": { "$sum": 1 }
    }
 },
 { "$sort" : { "_id" : -1}}
 ])

Anyone help will be much appreciated, thanks


回答1:


There is no Group_Concat kind of functionality in mongodb.

You can compare arrays for matching values in last group with $in operator in 3.4 version.

First $group to get all the distinct order status for a combination for order number and order status.

$sort to sort the order statuses.

Second $group to push all the sorted status values by order number.

Final $group to compare the statuses for each year against the input list of status and output total count for all matches.

db.order_summary.aggregate([{"$project":{
  "schedule_datetime":1,
  "order_number":1,
  "order_status":{"$ifNull":["$order_status",""]}
}},
{"$group":{
  "_id":{
    "order_number":"$order_number",
    "order_status":"$order_status"
   },
  "schedule_datetime":{"$first": "$schedule_datetime"} 
}},
{"$sort":{"_id.order_status": 1}},
{"$group":{
   "_id":{
    "order_number":"$_id.order_number"
   },
  "schedule_datetime":{"$first": "$schedule_datetime"},
  "order_status":{"$push": "$_id.order_status"}
}},
{"$group":{
  "_id":{"$substr":["$schedule_datetime",0,4]},
  "count":{
    "$sum":{
      "$cond": [
        {"$in": ["$order_status",[["SUCCESS"], ["","SUCCESS"]]]}, 
        1,
        0]
    }
  }
}},
{"$sort":{"_id":-1}}])


来源:https://stackoverflow.com/questions/48096432/convert-mysql-query-contains-sum-and-group-concat-to-mongodb-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!