SQL 查询的 WHERE 子句中的许多条件
您好,我在编写查询时遇到问题。我会很高兴收到一些建议!
我的表名为 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
构建可选子句时,请使用以下模式执行它们
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”;
至于这部分
如果您只想拥有 同时 8/1 和 9/1(或更多组合)的 tob_tag,那么您需要 GROUP BY 和 HAVING 子句。
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 becomesSELECT "TagsObjects"."tob_tag"
FROM "TagsObjects"
WHERE FALSE
OR TRUE
GROUP BY "TagsObjects"."tob_tag";
As for this part
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.
让我们从问题所在开始。您正在尝试查找“TagsObjects”.“tob_object”= 8 和“TagsObjects”.“tob_object”= 9 的行。“TagsObjects”.“tob_object”不能同时存在,因此无法返回任何行。
那你应该做什么?
从您的规范中,我了解到有几对 ("TagsObjects"."tob_object"、"TagsObjects"."tob_objectType"),其中两个字段都不是常量。您想要创建为每对返回的所有行的并集。
命名子查询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.
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.