我有以下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新手,所以希望我不会错过任何明显的东西,但任何帮助都表示赞赏。
干杯,
马特
幸运的是,使用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
)
显示任何成功的结果
什么是成功的结果?具有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
你可以使用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以获取有关查找孤立行的信息。