繁体   English   中英

仅根据Knex中的列选择不同的行

[英]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并尝试查找具有相同idFooid较大的行,如果找不到,则为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM