Drizzle ORM 如何在 WHERE 中使用子查询

问题描述 投票:0回答:1

假设您有以下 SQLite 数据,位于名为“A”的表中

id  name    last_updated
1   Apple   100
2   Banana  100
3   Apple   200
4   Banana  200
5   Carrot  200
6   Banana  300
7   Apple   300

您想要获取与最大的last_updated对应的每个名称的条目,假设last_updated是<= to a certain parameter value, for example given

last_updated <= 250
,结果应该是:

| id  | name   | last_updated |
| --- | ------ | ------------ |
| 3   | Apple  | 200          |
| 4   | Banana | 200          |
| 5   | Carrot | 200          |

在原始 SQL 中,设置为:

-- INIT database
CREATE TABLE IF NOT EXISTS A (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    last_updated INTEGER NOT NULL
);
INSERT INTO A (name, last_updated) VALUES ('Apple', 100);
INSERT INTO A (name, last_updated) VALUES ('Banana', 100);
INSERT INTO A (name, last_updated) VALUES ('Apple', 200);
INSERT INTO A (name, last_updated) VALUES ('Banana', 200);
INSERT INTO A (name, last_updated) VALUES ('Carrot', 200);
INSERT INTO A (name, last_updated) VALUES ('Banana', 300);
INSERT INTO A (name, last_updated) VALUES ('Apple', 300);

如何编写 Drizzle 查询来实现此目的?

所以在原始 SQL 中,我可以通过 WHERE 子句中的子查询来实现这一点:

-- QUERY database
SELECT a.id, a.name, a.last_updated
FROM A AS a
WHERE a.last_updated = (
    SELECT MAX(last_updated)
    FROM A
    WHERE name = a.name
    AND last_updated <= 250
)
AND a.last_updated <= 250;

我在 Drizzle ORM 中尝试了很多变体,但似乎我就是无法得到正确的结果。 我最近的尝试看起来像这样:

const dayLuxonToBigint = 250

return await db
  .select()
  .from(A)
  .where(
    and(
      lte(a.last_updated, dayLuxonToBigint),
      sql`SELECT max(${A.last_updated}) FROM ${A}
WHERE id = a.id
AND ${A.last_updated} <= ${dayLuxonToBigint}`,
    ),
  );

希望有人能帮忙,谢谢!

node.js typescript sqlite subquery drizzle
1个回答
1
投票

您可以单独声明您的子查询。 为了使用 MAX 聚合 - 您需要按名称分组。

const subQuery = db.select({
   name: A.name,
   max_last_updated: sql<number>`cast(max(${A.last_updated}) as int)`.as('max_last_updated')`
 })
  .from(A)
  .where(lte(a.last_updated, dayLuxonToBigint))
  .groupBy(A.name)
  .as('subQuery');

await db.select()
  .from(A)
  .innerJoin(subQuery, and(
     eq(A.name, subQuery.name),
     eq(A.last_updated, subQuery.max_last_updated)
   ))

您可以在他们的文档中阅读建议的毛毛雨方法

© www.soinside.com 2019 - 2024. All rights reserved.