推进相当于“存在”

发布于 2024-10-15 03:10:08 字数 386 浏览 6 评论 0原文

我是 Propel 的新手,并且一直在阅读文档。但是,我还没有找到与 SQL 中的 EXISTS 和 NOT EXISTS 结构明确等效的方法。例如,.NET 中的 Linq 具有 Any()。在“惯用”Propel 中是否有相当于以下内容的内容?

SELECT a.column1, a column2, a.etc
FROM   TableA a
WHERE  NOT EXISTS (SELECT 1
                   FROM   TableB b
                   WHERE  b.someIdColumn = a.someIdColumn
                   AND    b.aNullableDateColumn IS NULL)

I am new to Propel and have been reading the documentation. But, I have not found a clear equivalent to the EXISTS and NOT EXISTS constructs from SQL. Linq in .NET, for instance, has Any(). Is there an equivalent to the following in "idiomatic" Propel?

SELECT a.column1, a column2, a.etc
FROM   TableA a
WHERE  NOT EXISTS (SELECT 1
                   FROM   TableB b
                   WHERE  b.someIdColumn = a.someIdColumn
                   AND    b.aNullableDateColumn IS NULL)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

软糖 2024-10-22 03:10:09

与 propel 1.6 一样,您现在可以使用 Criteria::INCriteria::NOT_IN

示例:选择不在 UserGroup 中的所有用户

$users = UserQuery::create()->filterById(UserPerUserGroupQuery::create()->select('user_id')->find(), CRITERIA::NOT_IN)
                             ->orderByUserName()
                             ->find();

As in propel 1.6 u now can use Criteria::IN and Criteria::NOT_IN

Example : Select all users that are not in an UserGroup

$users = UserQuery::create()->filterById(UserPerUserGroupQuery::create()->select('user_id')->find(), CRITERIA::NOT_IN)
                             ->orderByUserName()
                             ->find();
话少情深 2024-10-22 03:10:09

我认为你可以将查询重写为:

SELECT
  a.column1,
  a.column2,
  a.etc
FROM
  TableA a
WHERE
  (SELECT
    COUNT(*)
  FROM
    TableB b
  WHERE
    b.someIdColumn = a.someIdColumn
      AND
    b.aNullableDateColumn IS NULL
  ) > 0

这在 Propel 中很容易实现。

或者在 Propel 中更干净、更容易完成:

SELECT
  a.column1,
  a.column2,
  a.etc
FROM
  TableA a
    LEFT JOIN
  TableB b ON (b.someIdColumn = a.someIdColumn)
WHERE
  b.aNullableDateColumn IS NULL
    AND
  b.primaryKeyColumn IS NOT NULL

I think you could rewrite the query as:

SELECT
  a.column1,
  a.column2,
  a.etc
FROM
  TableA a
WHERE
  (SELECT
    COUNT(*)
  FROM
    TableB b
  WHERE
    b.someIdColumn = a.someIdColumn
      AND
    b.aNullableDateColumn IS NULL
  ) > 0

which is easily doable in Propel.

Or even cleaner and easier to accomplish in Propel:

SELECT
  a.column1,
  a.column2,
  a.etc
FROM
  TableA a
    LEFT JOIN
  TableB b ON (b.someIdColumn = a.someIdColumn)
WHERE
  b.aNullableDateColumn IS NULL
    AND
  b.primaryKeyColumn IS NOT NULL
终难愈 2024-10-22 03:10:09

Propel 2 可以做:

TableAQuery::create()
  ->useTableBNotExistsQuery()
  ->filterByNullableDateColumn(null)
  ->endUse()
  ->find();

或者

$nestedB = TableBQuery::create()
  ->filterByNullableDateColumn(null)
  ->where('TableB.someIdColumn = TableA.someIdColumn');
TableAQuery::create()->whereExists(nestedB)->find();

Propel 2 can do:

TableAQuery::create()
  ->useTableBNotExistsQuery()
  ->filterByNullableDateColumn(null)
  ->endUse()
  ->find();

or

$nestedB = TableBQuery::create()
  ->filterByNullableDateColumn(null)
  ->where('TableB.someIdColumn = TableA.someIdColumn');
TableAQuery::create()->whereExists(nestedB)->find();
撩心不撩汉 2024-10-22 03:10:08

经过更多的挖掘后,我相信我已经找到了我的问题的答案,或者至少是目前可用的答案。

EXISTS 或 NOT EXISTS 之后是子查询。虽然这个事实似乎是显而易见的,但我最初并没有想到将我的帮助搜索集中在子查询上。我发现了很少 有关该主题的资源。本质上,选项是使用 JOIN 重写查询(这是 @Kaltas 答案的核心)或使用 Criteria::CUSTOM。我决定我可能更喜欢第二个选项,因为它允许我保留子查询,可能有助于我的数据库性能。

然后,我阅读了很多有关 Criteria::CUSTOM 的内容,但唯一真正对我有帮助的是阅读 Propel 1.5 源代码。这真的很简单。只需将子查询逐字(使用数据库的表和列名称,不是 Propel 的对象名称)以及 EXISTS 或 NOT EXISTS 放在 where 调用中,就像:

TableAQuery::create()
    ->where('NOT EXISTS (SELECT 1 FROM TableB WHERE TableA.someIdColumn = TableB.someIdColumn AND TableB.aNullableDateColumn IS NULL)')
    ->find();

就这么简单。在内部,where 方法会通过几种可能性来解释该子句,并且没有找到匹配项,它将该子句视为 Criteria::CUSTOM 并将其插入到SQL 查询按原样。因此,例如,我无法使用表别名。

如果我有时间,也许我会采用一种更“ORM”的方式来完成此任务并提交补丁。不过,也许有人会比我先一步。

After doing some more digging, I believe I have an answer to my question, or at least as good an answer as is currently available.

What comes after EXISTS or NOT EXISTS is a subquery. While that fact seems obvious, it did not originally occur to me to focus my search for help on subqueries. I found a few resources on the topic. Essentially, the options are to rewrite the query using JOINs (as is the heart of the answer by @Kaltas) or to use Criteria::CUSTOM. I decided I would likely prefer the second option, since it allows me to keep the subquery, potentially helping my database performance.

I did a lot of reading, then, about Criteria::CUSTOM, but the only reading that really helped me was reading the Propel 1.5 source. It's very simple, really. Just put the subquery, verbatim (using the database's table and column names, not Propel's object names) along with EXISTS or NOT EXISTS in the where call, like:

TableAQuery::create()
    ->where('NOT EXISTS (SELECT 1 FROM TableB WHERE TableA.someIdColumn = TableB.someIdColumn AND TableB.aNullableDateColumn IS NULL)')
    ->find();

It's that simple. Internally, the where method goes through a few possibilities for interpreting the clause, and finding no matches, it treats the clause as being of Criteria::CUSTOM and inserts it into the SQL query as-is. So, I could not use table aliases, for example.

If I ever have time, maybe I'll work on a more "ORM-ish" way to do this and submit a patch. Someone will probably beat me to it, though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文