[英]Selecting only distinct rows based on a column in Knex
我正在使用Knex (一个非常不错的SQL构建器)。
我有一个名为Foo
的表,该表有3列
+--------------+-----------------+
| id | PK |
+--------------+-----------------+
| idFoo | FK (not unique) |
+--------------+-----------------+
| serialNumber | Number |
+--------------+-----------------+
我想选择idFoo IN (1, 2, 3)
所有行。
但是我想避免基于相同idFoo
重复记录。
由于该列不是唯一的,因此可能有许多行具有相同的idFoo
。
我上面的查询当然将全部返回idFoo IN (1, 2, 3)
,甚至重复。
db.select(
"id",
"idFoo",
"age"
)
.from("foo")
.whereIn("idFoo", [1, 2, 3])
但是,这将返回具有重复idFoo
的结果,如下所示:
+----+-------+--------------+
| id | idFoo | serialNumber |
+----+-------+--------------+
| 1 | 2 | 56454 |
+----+-------+--------------+
| 2 | 3 | 75757 |
+----+-------+--------------+
| 3 | 3 | 00909 |
+----+-------+--------------+
| 4 | 1 | 64421 |
+----+-------+--------------+
我需要的是:
+----+-------+--------------+
| id | idFoo | serialNumber |
+----+-------+--------------+
| 1 | 2 | 56454 |
+----+-------+--------------+
| 3 | 3 | 00909 |
+----+-------+--------------+
| 4 | 1 | 64421 |
+----+-------+--------------+
我可以得出结果,并使用Javascript过滤掉重复项。 我特别想避免这种情况,并用Knex编写。
问题是如何使用Knex代码执行此操作?
我知道可以使用普通SQL(也许使用GROUP BY
),但是我特别想在不使用原始SQL的情况下通过“纯” knex实现此目的。
在普通的sql中,您可以这样做。
您执行self join
并尝试查找具有相同idFoo
但id
较大的行,如果找不到,则为NULL
。 并且会知道你是更大的。
SELECT t1.id, t1.idFoo, t1.serialNumber
FROM foo as t1
LEFT JOIN foo as t2
ON t1.id < t2.id
AND t1.idFoo = t2.idFoo
WHERE t2.idFoo IS NULL
因此,请检查knex.js上的left join
编辑:
只需检查文档即可构建此文件(未经测试):
knex.select('t1.*')
.from('foo as t1')
.leftJoin('foo as t2', function() {
this.on('t1.id', '<', 't2.id')
.andOn('t1.idFoo ', '=', 't2.idFoo')
})
.whereNull("t2.idFoo")
Knex.js原生支持groupBy 。 你可以写:
knex('foo').whereIn('id',
knex('foo').max('id').groupBy('idFoo')
)
将其重写为以下SQL:
SELECT * FROM foo
WHERE id IN (
SELECT max(id) FROM foo
GROUP BY idFoo
)
请注意,您需要使用子选择来确保您不会混合来自同一组内不同行的值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.