[英]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.