Sequelize查询以查找所有落在日期范围内的记录。

64

我有一个具有列的模型:

from: { type: Sequelize.DATE }
to: { type: Sequelize.DATE }

我想查询所有记录,其from或者to落在日期范围[开始日期, 结束日期]之间。

我尝试了一些类似的方法:

const where = {
    $or: [{
        from: {
            $lte: startDate,
            $gte: endDate,
        },
        to: {
            $lte: startDate,
            $gte: endDate,
        },
    }],
};

类似这样的:

SELECT * from MyTable WHERE (startDate <= from <= endDate) OR (startDate <= to <= endDate

什么是问题?你有收到任何错误吗?这个查询生成的 SQL 是什么? - piotrbienias
这是因为您的查询有误。from: { $gte: startDate, $lte:endDate } - frlinw
4个回答

87

对我有效的解决方案是:

// here startDate and endDate are Date objects
const where = {
    from: {
        $between: [startDate, endDate]
    }
};

了解更多关于运算符的信息,请参考:http://docs.sequelizejs.com/en/latest/docs/querying/#operators

注意:MYSQL中,between比较运算符是包含的,这意味着它等同于表达式(startDate <= from AND from <= endDate)


2
$between是边界排除的吗?如果from === startDate || from === endDate,它是否包含在内? - Shankar Regmi
1
@ShankarRegmi 在MYSQL中,“Between”比较是包含的。更多信息请参见https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_between - Akshay Pratap Singh
我认为这不正确。如果“from”日期在开始日期之前,则“to”日期仍可能在开始和结束之间。如果目标是检查重叠时间段,则需要检查“to”是否在开始之前,并且“from”是否在结束之后。 - Pointy

37
尝试这个条件。我认为你所询问的将会实现。
对于Sequelize的新版本:
const where = {
    [Op.or]: [{
        from: {
            [Op.between]: [startDate, endDate]
        }
    }, {
        to: {
            [Op.between]: [startDate, endDate]
        }
    }]
};

或者按照您的代码结构:

const where = {
    $or: [{
        from: {
            $between: [startDate, endDate]
        }
    }, {
        to: {
            $between: [startDate, endDate]
        }
    }]
};

更多信息,请参考Sequelize官方文档

2
为什么在“从”和“到”位置都需要开始和结束日期? - Steven Matthews
@CecilRodriguez 需要检查两个不同字段中的任何日期是否在这些日期之间。他在问题中特别提到了这一点。 - M.A.K. Ripon

13

步骤 1

从 SEQUELIZE 中要求 Op:

const { Op } = require('sequelize');

第二步

声明两个常量:

const startedDate = new Date("2020-12-12 00:00:00");
const endDate = new Date("2020-12-26 00:00:00");

第三步
table.findAll({where : {"fieldOfYourDate" : {[Op.between] : [startedDate , endDate ]}}})
.then((result) =>  res.status(200).json({data : result}))
.catch((error) =>  res.status(404).json({errorInfo: error}))

1
它会报错 Types of property '[Op.between]' are incompatible.,下面的链接可以解决这个问题 https://dev59.com/oLroa4cB1Zd3GeqPeB84#60987727 我在这里放一下,以防有人尝试解决相同的问题。 - Vignesh Sundaramoorthy

6
我同意@VigneshSundaramoorthy的评论,即使[Op.between]可以使用日期字符串,但类型定义表明此用法并未得到官方支持。该操作需要数字数组,至少截至2021年12月28日的文档中没有使用Op.between获取日期范围的示例(仅适用于数字范围)。
然而,我们可以以符合类型的方式实现相同的结果,这也与Sequelize文档一致:
const where = {
  "date_field": {
    [Op.and]: {
      [Op.gte]: startOfDateRange,
      [Op.lte]: endOfDateRange
    }
  }
}

这也稍微有些优势,因为它更明确(搜索是包容性的),而不是依赖于 BETWEEN 的方言行为。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接