嗨,我在编写查询时遇到问题。我很乐意收到一些建议!
我的表名为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。
答案 0 :(得分:2)
构建可选子句时,请使用此模式
SELECT“TagsObjects”。“tob_tag”
来自“TagsObjects”
假的是什么?
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”;
但是,如果根本没有条件,那么将OR TRUE
添加到列表中,它就变为
SELECT“TagsObjects”。“tob_tag”
来自“TagsObjects”
假的是什么?
OR TRUE
GROUP BY“TagsObjects”。“tob_tag”;
至于这部分
我需要知道所有对的所有tob_tag都有共同点。
如果您只想要具有两者 8/1和9/1(或更多组合)的tob_tags,那么您需要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;
答案 1 :(得分:1)
让我们先从错误开始。您正在尝试查找“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";
named子查询matchingTgsObjects列出了为pair(8,1)和(8,2)找到的所有tob_tags。在主查询中选择实际标记,并使用group by子句选择不同的tob_tags,与解决方案一样。我使用了UNION ALL,因为分组是在主查询中完成的,我没有找到任何理由在此时修剪子查询中的重复行。您可以通过从UNION ALL中省略ALL来实现这一点。
您还可以直接在from部分中包含子查询,而不是使用命名子查询。
还有一种替代方法是在WHERE中匹配where子句中的OR条件(匹配对A)OR(匹配对B)。如果他看到使用过,那么我的同事就会变得更具弹道性:当需要在这种情况下匹配OR时,它会告诉我们可能需要对实际模型做些什么。