SQL 查询的 WHERE 子句中的许多条件

发布于 2024-10-19 09:43:13 字数 677 浏览 1 评论 0原文

您好,我在编写查询时遇到问题。我会很高兴收到一些建议!

我的表名为 TagObjects;它有 5 列,但对问题重要的 3 列是:tob_tag、tob_object 和 tob_objectType。

我需要通过查询实现以下目标:对于未知数量的对(tob_object,tob_objectType),我需要知道所有对的共同点的所有 tob_tag。

我尝试过这个查询(数字只是作为示例):

SELECT "TagsObjects"."tob_tag"
FROM "TagsObjects"
WHERE TRUE
AND ("TagsObjects"."tob_object" = 8 AND "TagsObjects"."tob_objecttype" = 1)
AND ("TagsObjects"."tob_object" = 9 AND "TagsObjects"."tob_objecttype" = 1)
GROUP BY "TagsObjects"."tob_tag";

WHERE TRUE 在那里,因为我正在动态构建查询。该查询适用于一对(WHERE 子句中的一个 AND),当我尝试使用两对(如我上面发布的示例)时,它不会返回任何行(并且数据就在那里!)。

如果有人知道我做错了什么或者知道我做错了什么,这将是一个很大的帮助!

使用 PostgreSQL 9.0.1。

Hi I'm having trouble writing a query. I will be very glad to receive some advice!

My table is called TagObjects; it has 5 columns, but the 3 important to the problem are: tob_tag, tob_object and tob_objectType.

What I need to achieve with the query is the following: with an unknown number of pairs (tob_object, tob_objectType) I need to know all the tob_tag all the pairs have in common.

I have tried with this query (the numbers are just as an example):

SELECT "TagsObjects"."tob_tag"
FROM "TagsObjects"
WHERE TRUE
AND ("TagsObjects"."tob_object" = 8 AND "TagsObjects"."tob_objecttype" = 1)
AND ("TagsObjects"."tob_object" = 9 AND "TagsObjects"."tob_objecttype" = 1)
GROUP BY "TagsObjects"."tob_tag";

The WHERE TRUE is there because I'm building the query dynamically. This query works for one pair (one AND in the WHERE clause), when I tried it with two pairs (like the example I post above) it doesn't return any rows (and the data is there!).

If someone knows what I'm doing wrong or a way to do this it will be a BIG HELP!

Using PostgreSQL 9.0.1.

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

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

发布评论

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

评论(2

把回忆走一遍 2024-10-26 09:43:13

构建可选子句时,请使用以下模式执行它们

SELECT "TagsObjects"."tob_tag"
来自“标签对象”
错误之处
OR ("TagsObjects"."tob_object" = 8 AND "TagsObjects"."tob_objecttype" = 1)
OR ("TagsObjects"."tob_object" = 9 AND "TagsObjects"."tob_objecttype" = 1)
按“TagsObjects”分组。“tob_tag”;

但是,如果根本没有条件,则将 OR TRUE 添加到列表中,这样它就变成

SELECT "TagsObjects"."tob_tag"
来自“标签对象”
错误之处
或正确
按“TagsObjects”分组。“tob_tag”;

至于这部分

我需要知道所有对的共同点的所有 tob_tag。

如果您只想拥有 同时 8/1 和 9/1(或更多组合)的 tob_tag,那么您需要 GROUP BY 和 HAVING 子句。

SELECT "TagsObjects"."tob_tag"
FROM "TagsObjects"
WHERE FALSE
OR ("TagsObjects"."tob_object" = 8 AND "TagsObjects"."tob_objecttype" = 1)
OR ("TagsObjects"."tob_object" = 9 AND "TagsObjects"."tob_objecttype" = 1)
GROUP BY "TagsObjects"."tob_tag"
HAVING COUNT(*) = 2;

When building your optional clauses, do them using this pattern

SELECT "TagsObjects"."tob_tag"
FROM "TagsObjects"
WHERE FALSE
OR ("TagsObjects"."tob_object" = 8 AND "TagsObjects"."tob_objecttype" = 1)
OR ("TagsObjects"."tob_object" = 9 AND "TagsObjects"."tob_objecttype" = 1)
GROUP BY "TagsObjects"."tob_tag";

However, if there are no conditions at all, then add OR TRUE to the list, so it becomes

SELECT "TagsObjects"."tob_tag"
FROM "TagsObjects"
WHERE FALSE
OR TRUE
GROUP BY "TagsObjects"."tob_tag";

As for this part

I need to know all the tob_tag all the pairs have in common.

If you only want tob_tags that have both 8/1 and 9/1 (or more combinations), then you need a GROUP BY and HAVING clause.

SELECT "TagsObjects"."tob_tag"
FROM "TagsObjects"
WHERE FALSE
OR ("TagsObjects"."tob_object" = 8 AND "TagsObjects"."tob_objecttype" = 1)
OR ("TagsObjects"."tob_object" = 9 AND "TagsObjects"."tob_objecttype" = 1)
GROUP BY "TagsObjects"."tob_tag"
HAVING COUNT(*) = 2;
烟酒忠诚 2024-10-26 09:43:13

让我们从问题所在开始。您正在尝试查找“TagsObjects”.“tob_object”= 8 和“TagsObjects”.“tob_object”= 9 的行。“TagsObjects”.“tob_object”不能同时存在,因此无法返回任何行。

那你应该做什么?

从您的规范中,我了解到有几对 ("TagsObjects"."tob_object"、"TagsObjects"."tob_objectType"),其中两个字段都不是常量。您想要创建为每对返回的所有行的并集。

WITH matchingTagsObjects AS (
    SELECT "TagsObjects"."tob_tag" 
    FROM "TagsObjects" 
    WHERE ("TagsObjects"."tob_object" = 8 AND "TagsObjects"."tob_objecttype" = 1)
    UNION ALL
    SELECT "TagsObjects"."tob_tag" 
    FROM "TagsObjects" 
    WHERE ("TagsObjects"."tob_object" = 9 AND "TagsObjects"."tob_objecttype" = 1)
 )
 SELECT "TagsObjects"."tob_tag"  
 FROM matchingTagsObjects
 GROUP BY "TagsObjects"."tob_tag";

命名子查询matchingTgsObjects 列出为(8,1) 和(8,2) 对找到的所有tob_tag。与您的解决方案一样,在主查询中选择实际标签,并使用 group by 子句选择不同的 tob_tags。我使用 UNION ALL 是因为分组是在主查询中完成的,并且此时我没有找到任何理由在子查询中删除重复的行。您可以通过从 UNION ALL 中删除 ALL 来实现这一点。

您还可以将子查询直接包含在 from 部分中,而不是使用命名子查询。

还有一种替代方法是在 where 子句中使用 OR 条件,如 WHERE(匹配 A 对)OR(匹配 B 对)。我的一位同事如果看到这样的用法,他一定会大发雷霆:当在这种情况下需要使用 OR 来进行匹配时,它表明可能需要对实际模型做一些事情。

Let's start with what's wrong. You are trying to find a row where both "TagsObjects"."tob_object" = 8 and "TagsObjects"."tob_object" = 9. The "TagsObjects"."tob_object" cannot be both at the same time so no rows cannot be returned.

What you should do then?

From you specification I gather that there are several pairs of ("TagsObjects"."tob_object", "TagsObjects"."tob_objectType") where neither field is a constant. You want to create an union of all rows that are returned for each pair.

WITH matchingTagsObjects AS (
    SELECT "TagsObjects"."tob_tag" 
    FROM "TagsObjects" 
    WHERE ("TagsObjects"."tob_object" = 8 AND "TagsObjects"."tob_objecttype" = 1)
    UNION ALL
    SELECT "TagsObjects"."tob_tag" 
    FROM "TagsObjects" 
    WHERE ("TagsObjects"."tob_object" = 9 AND "TagsObjects"."tob_objecttype" = 1)
 )
 SELECT "TagsObjects"."tob_tag"  
 FROM matchingTagsObjects
 GROUP BY "TagsObjects"."tob_tag";

The named subquery matchingTgsObjects lists all tob_tags that are found for pairs (8,1) and (8,2). The actual tags are selected in the main query and distinct tob_tags are selected using the group by clause as with you solution. I used UNION ALL because the grouping is done in the main query and I didn't find any reason to prune duplicate rows in the subquery at this point. You can achieve that by leaving out the ALL from UNION ALL.

You can also include the subquery directly in the from part instead of using a named subquery.

There's also an alternative that you use OR conditions in the where clause as in WHERE (matches pair A) OR (matches pair B). A co-worker of mine would go ballistic if he saw that used: when an OR is needed to for matching in this kind of scenario it tells that there might be something to be done with actual model.

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