【问题标题】:Counting number of rows matching criteria between two dates计算两个日期之间匹配条件的行数
【发布时间】:2016-12-20 19:04:48
【问题描述】:

我正在尝试查询 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;

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

【问题讨论】:

  • 你想要什么不清楚,但它看起来可以而且应该是一个简单的 SQL 问题,不应该通过后处理来解决,而是使用正确的 SQL 查询。
  • @DenysSéguret 我正在尝试获取状态字段具有特定值且位于两个日期之间的行数。我的查询为我提供了每行而不是每天的计数,因此我尝试对结果进行后处理并汇总每天和每小时的数据,具体取决于提供的日期范围。

标签: node.js postgresql sequelize.js


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2019-04-20
    • 1970-01-01
    • 1970-01-01
    • 2015-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    相关资源
    最近更新 更多