获取包含一对多的行。但不是另一个

Get Rows that are include one many to many. but not another

我在处理这个查询时遇到了一些问题。我想针对所有具有包含名称 'G6' 的适用性但与具有名称 'n2' 的应用程序没有多对多关系的功能过滤我的功能。我现在有:

SELECT inner.* 
FROM 
    (SELECT feat.* 
    FROM Features feat
        INNER JOIN Feature _has_Applicability feat_app 
            ON feat_app.feature_id = feat.id
        INNER JOIN Applicability app 
            ON feat_app.applicability_id = app.id 
                AND app.name like '%G6%'
    WHERE feat.deleted_time = '0000-00-00 00:00:00'
    GROUP BY feat.id
    ) AS inner
    INNER JOIN Feature_has_Applicability out_feat_app 
        ON out_feat_app.feature_id = inner.id
    INNER JOIN Applicability app 
        ON out_feat_app.applicability_id = app.id 
            AND app.name NOT LIKE '%N2%'
GROUP BY inner.id
HAVING count (*) = 1

从功能到适用性,我有很多选择

特征 id 国际小学 deleted_time日期时间

适用性 id INT初级 name VARCHAR(45)

Feature_has_Applicability feature_id 智力 applicability_id 积分

示例:
我的功能 A 具有名为 N2 和 G6
的应用程序 我有功能 B,适用性为 G6,N7
我有适用性为 N2

的特征 C

我只想return编辑功能 B,因为它包括 G6 但不包括 N2。

就与它们具有多对多关系的特征而言,G6 是 A,N2 是 B。

这似乎仍然 return 具有适用于 'n2' 的功能。你能看出我做错了什么吗?谢谢。

您的第一个子查询似乎没问题。就个人而言,我不确定为什么您仍然只根据此查询而不查看数据库就得到 'n2' 记录。也许是因为您在查询中使用了大写 'N2'?运算符区分大小写。

虽然我建议你使用NOT EXISTS。它会使代码更容易理解其意图。试试这个:

SELECT *
FROM 
  features feat
  INNER JOIN feature_has_applicability feat_app ON feat_app.feature_id = feat.id
  INNER JOIN applicability app ON app.id = feat_app.applicability_id
    AND app.name LIKE '%G6%'
WHERE
  feat.delete_time = '0000-00-00 00:00:00'
  AND NOT EXISTS (
    SELECT
       *
    FROM
      feature_has_applicability out_feat_app
      INNER JOIN applicability out_app ON out_app.id = out_feat_app.applicability_id
        AND app.name LIKE '%N2%'
    WHERE
      out_feat_app.feature_id = feat.id
   )

使用NOT EXISTS有助于简化代码。所以在这种情况下,主要查询更容易理解,我们希望在其中找到具有 'G2' 适用性的特征记录。但是我们只想要不具有 'N2' 适用性的记录,这些记录属于所选要素记录的 ID。

我对 GROUP BYHAVING count(*) = 1 的目的感到困惑。如果您按其 ID 对其进行分组并期望每个组只有一个记录,那么这是否意味着每个过滤的功能记录只有一个 'G6' 适用性记录,因此您不需要担心过滤掉 'N2' 条记录?除非有奇怪的情况,例如在同一适用性记录中同时具有 'G6''N2' 关键字。

另一个提示,对于你的子查询,你不应该使用保留关键字作为标识符。在这种情况下,您将子查询称为 "inner",这是一种不好的做法,在其他数据库引擎中可能根本不是 运行。或许你可以称它为 "g2_feature".