【问题标题】:Building a MySQL query from optional filters in Express JS从 Express JS 中的可选过滤器构建 MySQL 查询
【发布时间】:2021-03-21 22:40:19
【问题描述】:

对不起,如果这是一个愚蠢的问题,但我是新来表达和 MySQL,我无法在任何地方找到解决方案。

我需要根据来自 HTML 表单的一些用户输入过滤器创建一个 MySQL 查询。 参数是这样的:

let sDate = req.body.startDate;
let eDate = req.body.endDate;
let param1 = req.body.param1;
let param2 = req.body.param2;
let param3 = req.body.param3;
let param4 = req.body.param4;

如果所有参数都不为空,我将使用的普通查询将是

const query = `
SELECT * FROM table
WHERE
date BETWEEN ? AND ?
AND col1 = ?
AND col2 = ?
AND col3 = ?
AND col4 = ?;`

db.query(query, [startDate, endDate, param1, param2, param3, param4], (e, rows)=>{});

但是每个参数都可以为空,所以有很多可能的过滤器组合。

有没有办法用一个查询来查询数据库?我可以在许多 if-else 语句中处理它,但感觉不对。

提前感谢您的帮助!

【问题讨论】:

  • 恕我直言,您没有就您的问题告诉我们足够多的信息,我们无法提供帮助。请edit它,或者问另一个。你的SQL将查询一个表:请给我们看。请解释您的四个param 值如何表达搜索标准。过程 (javascript) 领域和声明性 (SQL) 领域之间的接口需要很高的精度。
  • @O.Jones 对此感到抱歉!我已经编辑了一个查询,我将在提供所有参数的场景中使用该查询。我正在寻找的是是否有一种方法可以创建一个不考虑 WHERE 语句中的空值的查询。

标签: javascript mysql node.js express


【解决方案1】:

对于您的col1 = ? 模式,您可以使用(? IS NULL OR ? = col1)

对于您的日期匹配,您可以这样做。

   WHERE date <= IF( ? IS NOT NULL THEN ? ELSE '2999-12-31')
     AND date >= IF( ? IS NOT NULL THEN ? ELSE '1000-01-01')

但请注意参数出现两次。所以你的查询是

const sql = `
SELECT *
  FROM tbl
 WHERE date <= IF(? IS NOT NULL, ?, '2999-12-31')
   AND date >= IF(? IS NOT NULL, ?, '1000-01-01')
   AND (? IS NULL OR col1 = ?)
   AND (? IS NULL OR col2 = ?)
   AND (? IS NULL OR col3 = ?)
   AND (? IS NULL OR col4 = ?);`

你会像这样调用它。

const params = [startDate, startDate, 
                endDate, endDate,
                param1, param1, 
                param2, param3, 
                param2, param3, 
                param4, param4]

db.query(query, params, (e, rows)=>{});

但是当心:这种查询对于数据库服务器中的查询优化软件来说是一个臭名昭著的边缘案例。它不能很好地说明您想要什么来使用表统计信息来选择正确的索引。不过,一定要在上面放一个索引

(date, col1, col2, col3, col4)

对于这个查询。您可能有一个日期范围。

这可能会很慢,尤其是在该表非常大的情况下。每次处理请求时,最好从字符串构建自定义查询。查询优化器比带有? IS NULL OR 子句的东西更能理解此类内容。

WHERE date <= ?
  AND date >= ?
  AND col2 = ?
  AND col3 = ?

【讨论】:

  • 我用过IF(? IS NOT NULL, ?, '1000-01-01')
  • 啊,我明白了,感谢您指出我的错误。已编辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-04
  • 2013-05-01
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多