SQL查询的WHERE子句中的许多条件
嗨我在编写查询时遇到了问题。我会很乐意收到一些建议!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。
让我们从什么是错的开始。您试图在“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_tags。在主查询中选择实际标记,并使用group by子句选择不同的tob_tags,与您的解决方案一样。我使用了UNION ALL,因为分组是在主查询中完成的,并且我没有找到任何理由在此时删除子查询中的重复行。您可以通过从UNION ALL中删除ALL来实现这一点。
您也可以直接在子部分中包含子查询,而不是使用命名子查询。
还有一种替代方法,您在where子句中使用OR条件,如WHERE(匹配对A)或(匹配B对)。如果他看到了这个用法,我的一个同事就会发生冲突:当在这种情况下需要OR来进行匹配时,它会告诉我们可能需要用实际模型来完成某些工作。
作为此附录 - 请特别提供预期的输入数据和内容你期望输出是。 – 2011-02-28 23:47:29
命名的子查询可以通过合并查询通过'tob_object'或'tob_objecttype':'WHERE'TagsObjects“。”“tob_objecttype”= 1 AND“TagsObjects”。“tob_object”IN(8,9)'' – 2011-03-01 00:01:27
在构建您的可选条款,做他们使用这种模式
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”;
但是,如果没有条件的话,那么加OR TRUE
到列表中,因此它成为
SELECT “TagsObjects”。 “tob_tag”
FROM “TagsObjects”
WHERE FALSE
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;
丢掉TRUE;通过OR来代替AND来加入替代品。 并将SQL关键字(如FROM,WHERE和GROUP BY)放在行首。 – 2011-02-28 23:48:36
@Jonathan,你可以责怪我糟糕的格式。我添加了换行符(SQL片段最初是一行),但没有将它们添加到最佳位置。我现在要解决这个问题。 – 2011-02-28 23:52:00
YOu需要使用OR而不是AND作为您的查询的一部分... TRUE AND((..)OR(..)OR(..)) – MatBailie 2011-03-01 01:18:37