You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Prisma按最新ProductEvent的status过滤Product?

解决方案:按最新ProductEvent的status筛选Product

首先明确:你原来的查询逻辑问题在于,include中的orderBy和take仅控制返回的关联数据,不会影响where子句的过滤规则——where.events.some会检查该Product的所有关联事件,而非你指定的最新那一条。

以下是几种可行的实现方式:

方法1:利用子查询匹配最新事件状态(Prisma ORM写法)

通过子查询获取每个Product的最新事件时间,再筛选状态匹配的记录:

const targetStatus = "WHATEVER_STATUS";

await this.client.product.findMany({
  include: {
    events: {
      orderBy: { datetime: "desc" },
      take: 1,
    },
  },
  where: {
    events: {
      some: {
        status: targetStatus,
        // 限定该事件是当前Product的最新事件
        datetime: {
          equals: Prisma.sql`(SELECT MAX(datetime) FROM "ProductEvent" WHERE "productId" = "Product"."productId")`
        }
      }
    }
  }
});

方法2:使用Exists子查询(更严谨的过滤)

如果需要避免匹配到多个同时间的最新事件(比如某Product有多个同一时间的事件),可以用exists子查询精准定位:

const targetStatus = "WHATEVER_STATUS";

await this.client.product.findMany({
  include: {
    events: {
      orderBy: { datetime: "desc" },
      take: 1,
    },
  },
  where: {
    exists: {
      select: { productId: true },
      from: "ProductEvent",
      where: {
        productId: Prisma.sql`"Product"."productId"`,
        status: targetStatus,
        datetime: Prisma.sql`(SELECT MAX(datetime) FROM "ProductEvent" WHERE "productId" = "Product"."productId")`
      }
    }
  }
});

方法3:原生SQL查询(性能最优)

当数据量较大时,原生SQL的关联查询性能更优,逻辑是先预查询每个Product的最新事件,再关联筛选:

const targetStatus = "WHATEVER_STATUS";

const result = await this.client.$queryRaw`
  SELECT p.*, e.*
  FROM "Product" p
  INNER JOIN (
    -- 子查询获取每个Product的最新事件
    SELECT pe."productId", pe."datetime", pe."status", pe."productEventId"
    FROM "ProductEvent" pe
    WHERE (pe."productId", pe."datetime") IN (
      SELECT "productId", MAX("datetime")
      FROM "ProductEvent"
      GROUP BY "productId"
    )
  ) e ON p."productId" = e."productId"
  WHERE e."status" = ${targetStatus};
`;

内容的提问来源于stack exchange,提问作者sharkdarras

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 04:15:29