计算符合两个日期之间条件的行数

时间:2016-12-20 10:13:19

标签: node.js postgresql sequelize.js

我正在尝试在postgres db表中查询与时间范围之间的某些条件匹配的行数。我正在使用nodejs的sequelize orm。 在我的控制器方法中,我有一个查询

var query = 'SELECT o.ordered_at, COUNT(o.id) AS order_count FROM "Orders" o WHERE status = :status AND o.ordered_at >= :lower_limit AND o.ordered_at <= :upper_limit GROUP BY o.id ORDER BY o.ordered_at DESC';

      models.sequelize.query(query, queryOptions).
      then(function (orders) {
        res.status(200).json(response);
      }).
      catch(function (err) {
        logger.error(err);
        res.status(500).json(err.message);
      })

这会产生这样的响应

[
  {
    "ordered_at": "2016-12-10T16:05:46.525Z",
    "order_count": "1"
  },
  {
    "ordered_at": "2016-12-10T16:03:46.429Z",
    "order_count": "1"
  },
  {
    "ordered_at": "2016-12-10T16:01:46.440Z",
    "order_count": "1"
  },
  {
    "ordered_at": "2016-12-05T12:20:18.714Z",
    "order_count": "1"
  },
  {
    "ordered_at": "2016-12-05T12:18:18.650Z",
    "order_count": "1"
  },
  {
    "ordered_at": "2016-12-03T12:16:18.658Z",
    "order_count": "1"
  }
]

您可以看到查询返回每行的order_count而不是每个订单,所以我尝试在这里转换数据

  var data = [],
      lower_time_limit = t(new Date());

  var range = _.range(30),
      month_lower_limit = t(lower_time_limit).subtract(1, 'M').startOf('day');

  var lower_limit,
      limit,
      upper_limit;

  _.forEach(range, function (day, key) {
      limit = t(month_lower_limit);
      lower_limit = t(limit.add(day, 'd'));
      upper_limit = t(limit.add(1, 'd'));

      _.forEach(orders, function (order, index) {
        var count = 0;
        if (t(order.ordered_at).isBetween(lower_limit, upper_limit, 'second', '[)')) {
          var orderCount = count + parseInt(order.order_count);
          data.push({date: lower_limit, count: orderCount})
        }
      });
  });

  return data;

我知道我错过了什么,只是想不出来。

1 个答案:

答案 0 :(得分:0)

GROUP BY o.id将根据o.id生成一个组(即输出中的一行)。您想要一个组用于所有匹配的行,如果您完全省略GROUP BY,则会得到这些。

在输出中包含o.ordered_at并没有多大意义;如果您将多个匹配的行聚合到一个输出记录中,则不清楚您期望看到的ordered_at时间。

一旦你有一排输出,ORDER BY对你没什么好处。

考虑到所有这些:

SELECT COUNT(o.id) AS order_count
FROM "Orders" o
WHERE status = :status
  AND o.ordered_at >= :lower_limit
  AND o.ordered_at <= :upper_limit