SQL Query将列中的每个条目与另一列中的每个条目进行比较

时间:2018-03-05 17:04:20

标签: mysql

我有以下NIST 800-53控件的邻接列表:

id    item        content         parent
1     Checklists  null            0
2     NIST80053   NIST 80053      1
3     AC          Access Control  2
4     1           POLICY..        3
5     2           ACCOUNT..       3
6     3           ACCESS..        3

使用(800-53a)的NIST I版本的结构是某种item不会被使用的方式。任何此类item永远不会在item列中提及相应的parent。我正在尝试设计一个SQL查询,检查* id以查看"父母"中是否。列,并显示任何成功的结果。

现在我最接近的是这个简单的陈述,这是行不通的,因为它只检查每一行的id到同一行的父级(这将始终是不相等的,因为一个条目不能成为它自己的父母)。该行不是仅获取未分配的项目,而是返回整个表格:

 SELECT * FROM MySQL_IMPORTv2 where category_id != parent;

我是SQL的新手,所以我希望我不会错过任何明显的内容,但感谢任何帮助。

干杯,

马特

3 个答案:

答案 0 :(得分:0)

幸运的是,使用exists()语句很容易做到这一点。虽然我通常不建议对子查询进行限定,但exsits()的效率与它们的效率相当。如果子查询找到结果(任何匹配的结果),它将立即停止并返回true。

以下查询将返回列为另一个id的父级的任何id的所有四个字段

select
  id
  , item
  , content
  , parent
from
  MySQL_IMPORTv2
where
  exists (
    select
      1
    from
      MySQL_IMPORTv2 M
    where
      M.parent = MySQL_IMPORTv2.id
  )

答案 1 :(得分:0)

您可以使用join outer join使用select p.* from MySQL_IMPORTv2 p -- Parent Row left outer join MySQL_IMPORTv2 c -- Child Row on (p.id=c.parent) where c.id is null 表来查找其id未在任何其他行中用作父ID的行。

有关示例,请参阅此SQL Fiddle

p

此查询将占用MySQL_IMPORTv2表中的每一行(使用表别名c),并将其与表中的每一行(使用表别名left outer join)进行比较。由于p,无论c中是否存在匹配项,查询都会返回c中的每一行。但是,如果MySQL无法从加入条件中找到c中的匹配行,则会在null中填充c值,因此您可以通过在{中检查空值来对其进行过滤{1}}。因此,您将在表中找到在另一列中没有匹配值的所有行。

如果您想了解更多信息,可以查看Google以获取有关查找孤立行的信息。

答案 2 :(得分:0)

  

显示任何成功的结果

什么是成功的结果?具有id的记录也显示为父记录或父记录?后者可能会产生重复的条目,您是否只想为每个匹配的父级报告一个案例?你想和父母一起看原始唱片吗?

有多少记录没有父母?父母的平均子女数是多少?叶节点的平均深度是多少?表中定义了哪些索引?虽然这些功能不是必不可少的,但它们对解决方案的性能有很大的影响。

  

id item content parent

     

...

     

SELECT * FROM MySQL_IMPORTv2 where category_id!= parent;

什么category_id?

快速解决方案是:

SELECT parent.id, parent.item, parent.content, GROUP_CONCAT(children.id)
FROM MySQL_IMPORTv2 AS children
INNER JOIN FROM MySQL_IMPORTv2 AS parents
ON children.parent_id=parent.id
GROUP BY parent.id, parent.item, parent.content

找到有父母的孩子的详细信息:

SELECT children.*
FROM MySQL_IMPORTv2 AS children
INNER JOIN FROM MySQL_IMPORTv2 AS parents
ON children.parent_id=parent.id

然而,查看您的数据,这意味着所有记录都是id = 1的记录的子记录,因此您可能会要求....

SELECT parent.id, parent.item, parent.content, GROUP_CONCAT(children.id)
FROM MySQL_IMPORTv2 AS children
INNER JOIN FROM MySQL_IMPORTv2 AS parents
ON children.parent_id=parent.id
AND children.parent_id>1
GROUP BY parent.id, parent.item, parent.content