我想选择column1
小于或等于column2
的数据。但是,当我尝试使用<=
时,尽管column1
中的数据少于column2
,但结果还是空的。
我的代码:
router.get('/', function(req, res, next) {
db('items').select().where('column1', '<=', 'column2').then((notify)=>{
console.log(notify)
res.render('index', { title: 'Express', notify:notify })
})
})
和结果:
[]
您看到的是空的!
如果我使用更大或更等于:
.where('column1', '>=', 'column2')
我得到所有行:
[ RowDataPacket {
column_id: 1,
column1: 99,
column2: 10, },
RowDataPacket {
column_id: 2,
column1: 10,
column2: 10, },
RowDataPacket {
column_id: 3,
column1: 29,
column2: 12,} ]
这是为什么?
答案 0 :(得分:0)
问题是,SQL以这种方式工作,但Knex却不行! Knex实际上是将column1
的值与 string 'column2'进行比较。因此,就好像我们运行了SQL查询一样:
SELECT * FROM items
WHERE column1 <= 'column2';
现在,在MySQL(在我的示例中为MariaDB)中,将整数与字符串进行<=
比较将返回0
(假)。但是,>=
比较会返回1
,这说明了您看到的令人困惑的结果。其他一些数据库将显示错误(例如Postgres):
postgres=# SELECT 1 <= 'foo';
ERROR: invalid input syntax for integer: "foo"
LINE 1: SELECT 1 <= 'foo'; ^
但是MariaDB会让您摆脱它:
MariaDB [(none)]> SELECT 1 <= 'foo';
+------------+
| 1 <= 'foo' |
+------------+
| 0 |
+------------+
1 row in set (0.000 sec)
MariaDB [(none)]> SELECT 1 >= 'foo';
+------------+
| 1 >= 'foo' |
+------------+
| 1 |
+------------+
1 row in set (0.000 sec)
要解决此问题,您需要告诉Knex,您实际上想要比较右侧的列值,而不是字符串。您可以使用knex.ref
完成此操作。试试这个:
db("items")
.where("column1", "<=", db.ref("column2"))
.then(console.log)
.catch(console.error);
另请参阅:With knexjs, how do I compare two columns in the .where() function?。