SQL返回具有某些关联并排除其他关联的记录
我有以下疑问:SQL返回具有某些关联并排除其他关联的记录,sql,Sql,我有以下疑问: SELECT * FROM "AssetGroups" ag INNER JOIN "AssetGroupsTags" agt ON ag."Id" = agt."AssetGroupId" WHERE agt."TagId" IN (63, 77) AND agt."TagId" NOT IN (97); 这将返回ID为1031的记录。运行此查询时: SELECT "TagId" FROM "AssetGroupsTags" WHERE "AssetGroupId"
SELECT * FROM "AssetGroups" ag
INNER JOIN "AssetGroupsTags" agt ON ag."Id" = agt."AssetGroupId"
WHERE agt."TagId" IN (63, 77) AND agt."TagId" NOT IN (97);
这将返回ID为1031的记录。运行此查询时:
SELECT "TagId" FROM "AssetGroupsTags" WHERE "AssetGroupId" = 1031;
它返回97、63、27。我认为和
以及不在
中会排除记录1031,但这并没有发生
需要明确的是:我想返回所有标记ID为63或77,但标记ID为97的记录。假设我正确理解了您的问题,这里有一个选项使用
不存在
:
select *
from assetgroups ag
join assetgroupstags agt on ag.id = agt.assetgroupid
where agt.tagid in (63, 77)
and not exists (
select 1
from assetgroupstags agt2
where agt.assetgroupid = agt2.assetgroupid and agt2.tagid = 97
)
这将返回任何标记ID为63或77的
AssetGroup
,但不返回97的AssetGroup
。我只使用聚合:
SELECT agt."AssetGroupId"
FROM "AssetGroupsTags" agt
GROUP BY agt."AssetGroupId"
HAVING SUM(CASE WHEN agt."TagId" IN (63, 77) THEN 1 ELSE 0 END) > 0 AND
SUM(CASE WHEN agt."TagId" IN (97) THEN 1 ELSE 0 END) = 0;
如果您需要组id之外的其他字段,则可以将它们加入。
TagId
是字符串中以逗号分隔的列表值吗?如果是这样,你就不能在中使用。你在使用什么数据库管理系统?@Nick这不是字符串,而是返回的值列表。@eltiare,你能在这里粘贴一些当前场景中的数据示例吗?如果我理解正确,你可以使用self-join。是的,我认为这是最干净的方法。很高兴它有帮助。还有其他选择,比如使用带有null
检查的外部联接
,但我认为这是最明确的。@sgedes,从性能角度看,哪一个是好的,要么是自联接
,要么是使用不存在
?@GauravGenius--我相信这有点取决于数据库,但一般来说,存在
将在第一次匹配时短路,其中外部连接
将迭代所有匹配。话虽如此,在这种情况下,外部连接
将只有一条记录,因此我认为它们将产生几乎相同的执行计划。这里有一个潜在的相关帖子: