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

问题描述 投票:1回答:3

我有以下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

我正在使用的NIST版本(800-53a)的结构是某种item不会被使用的方式。任何这样的item永远不会有它在item专栏中提到的相应的parent。我正在尝试设计一个SQL查询,检查*每个id以查看它是否在“父”列中提到过,并显示任何成功的结果。

现在我得到的最接近的是这个简单的语句,这不起作用,因为它只检查每一行的id到同一行的父级(它总是不相等,因为一个条目不能是它自己的父级)。该行不是仅获取未分配的项目,而是返回整个表格:

 SELECT * FROM MySQL_IMPORTv2 where category_id != parent;

我是SQL新手,所以希望我不会错过任何明显的东西,但任何帮助都表示赞赏。

干杯,

马特

mysql
3个回答
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
  )

0
投票

显示任何成功的结果

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

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

id项目内容parent

...

SELECT * FROM MySQL_IMPORTv2其中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

0
投票

你可以使用join将你的表outer join给自己找到其id不用作任何其他行的父id的行。

有关示例,请参阅此SQL Fiddle

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

此查询将占用MySQL_IMPORTv2表中的每一行(使用表别名p),并将其与表中的每一行(使用表别名c)进行比较。由于left outer join,查询将返回p中的每一行,无论c中是否存在匹配。但是,无论MySQL在连接标准中找不到c中的匹配行,它都会使用c值填充null,因此您可以通过检查c中的空值来过滤它。因此,您将在表中找到在另一列中没有匹配值的所有行。

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

© www.soinside.com 2019 - 2024. All rights reserved.