将SQL输出限制为仅在子查询中找到的项目

时间:2015-04-21 01:54:53

标签: sql tsql sql-server-2012

好的,在这个例子中,你能否指出我正确的方向将此查询的输出限制为仅在where子句中找到的结果。我会解释更多..

SELECT
ServerName=substring(MN.object_text,patindex ('%Caption %',MN.object_text)+11,patindex('%"%',substring(MN.object_text,patindex ('%Caption %',MN.object_text)+11,80))-1)
/* ,MN.object_text */, p.name
FROM
[openview].[dbo].[sto_ov_managednode] MN
left outer join [openview].[dbo].[OV_PM_PolicyOnNode] PON
on pon.nodeid = mn.name
left outer join [openview].[dbo].[OV_PM_PolicyVersion] PV
on PV.policyversionid = pon.policyversionid
left outer join [openview].[dbo].[OV_PM_Policy] P
on P.PolicyId = pv.policyid
where p.name not in (select Name from dbo.OV_PM_Policy where PolicyId = any(select PolicyId from dbo.OV_PM_PolicyGroupAssignment where GroupId = '18681abc-097d-41cd-9782-e28d9a9f5fc4'))
and substring(MN.object_text,patindex ('%AgentBinaryFormatId%',MN.object_text)+22,1) <> '0' /* exclude non-managed nodes */
and substring(MN.object_text,patindex ('%OsVersionId%',MN.object_text)+14,2) = '18' /* include only Windows OS devices */
ORDER BY ServerName, name;

让我们说这会返回所有服务器名,而p.name不在我的查询中。这就是它应该按照书面形式做的......但我只想要那个服务器名称,如果它没有这些政策之一......并且只有它没有其中一个...没有列出它可能具有的其他政策..但不在该结果集中......我尝试过不同的联接,并且不使用....存在不存在...问题..是,当我使用那些......它并没有真正改变任何东西。

考虑一个文件夹结构..... p.name正在查找文件夹并查找其中的所有策略名称。有许多文件夹和许多其他政策......但在这里我只关心那个文件夹中的那些。因此,如果服务器A拥有该文件夹中的所有政策,我不想看到它。如果它有其他政策,我不在乎......但如果它已经丢失,即使其中一个我希望了解该文件夹中的政策。

所以基本上我想要它当前给我的输出..但是只有当发现的策略是在该组开始时。因此,我需要将输出限制为仅返回缺少该组策略的服务器。

更新 - sqlfiddle信息和更好的示例...感谢Mark for the sqlfiddle setup

create table sto_ov_managednode (
object_text varchar(100),
name varchar(100)
);

create table OV_PM_PolicyOnNode (
nodeid varchar(100),
policyversionid varchar(100)
);

create table OV_PM_PolicyVersion (
policyversionid varchar(100) unique,
policyid varchar(100)
);

create table OV_PM_Policy (
Name varchar(100),
PolicyId varchar(100)
);

create table OV_PM_PolicyGroupAssignment (
PolicyId varchar(100),
GroupId varchar(100),
PolicyVerisonId varchar(100) unique
);

insert into sto_ov_managednode values ('Caption ---Server1"---AgentBinaryFormatId---OsVersionId---18--','node1');
insert into sto_ov_managednode values ('Caption ---Server2"---AgentBinaryFormatId---OsVersionId---18--','node2');

insert into OV_PM_PolicyOnNode values ('node1','policyversionID1');
insert into OV_PM_PolicyOnNode values ('node1','policyversionID4');
insert into OV_PM_PolicyOnNode values ('node2','policyversionID1');

insert into OV_PM_PolicyVersion values ('policyversionid1','policyid1');
insert into OV_PM_PolicyVersion values ('policyversionid2','policyid1');
insert into OV_PM_PolicyVersion values ('policyversionid3','policyid2');
insert into OV_PM_PolicyVersion values ('policyversionid4','policyid2');
insert into OV_PM_PolicyVersion values ('policyversionid5','policyid3');
insert into OV_PM_PolicyVersion values ('policyversionid6','policyid3');


insert into OV_PM_Policy values ('policy A','policyid1');
insert into OV_PM_Policy values ('policy B','policyid2');
insert into OV_PM_Policy values ('policy C','policyid3');

insert into OV_PM_PolicyGroupAssignment values ('policyid1','Base Windows','policyversionid2');
insert into OV_PM_PolicyGroupAssignment values ('policyid2','Base Windows','policyversionid4');
insert into OV_PM_PolicyGroupAssignment values ('policyid3','Extra Windows','policyversionid5');

现在输出就是这个..

nodeName    policyName
node1       policy C
node2       policy B
node2       policy C

您会注意到这基本上是正确的..但我不想看到策略C,因为它不在基本Windows组中....我只需要看到一个策略是否从服务器中丢失...并且包含在我用于搜索的组中..

New SqlFiddle

Final Update

这是最终确实起作用的最终sql语句。谢谢你的努力,我很感激。

select ServerName=substring(MN.object_text,patindex ('%Caption %',MN.object_text)+11,patindex('%"%',substring(MN.object_text,patindex ('%Caption %',MN.object_text)+11,80))-1), "Policy" = P.name
FROM OV_PM_PolicyGroupAssignment PGA
left join OV_PM_Policy P on PGA.PolicyId = P.PolicyId
left join OV_PM_PolicyVersion PV on P.PolicyId = PV.policyid
cross join sto_ov_managednode MN
where PGA.GroupId = '18681abc-097d-41cd-9782-e28d9a9f5fc4'
and substring(MN.object_text,patindex ('%AgentBinaryFormatId%',MN.object_text)+22,1) <> '0' /* exclude non-managed nodes */
and substring(MN.object_text,patindex ('%OsVersionId%',MN.object_text)+14,2) = '18' /* include only Windows OS devices */
except
select ServerName=substring(MN.object_text,patindex ('%Caption %',MN.object_text)+11,patindex('%"%',substring(MN.object_text,patindex ('%Caption %',MN.object_text)+11,80))-1), P.name as policyName
from sto_ov_managednode MN
left join OV_PM_PolicyOnNode PON on pon.nodeid = mn.name
left join OV_PM_PolicyVersion PV on PV.policyversionid = pon.policyversionid
left join OV_PM_Policy P on P.PolicyId = pv.policyid
left join OV_PM_PolicyGroupAssignment PGA on P.PolicyId = PGA.PolicyId
where PGA.GroupId = '18681abc-097d-41cd-9782-e28d9a9f5fc4'
Order by ServerName, Policy;

1 个答案:

答案 0 :(得分:2)

我希望我理解你的架构足以正确回应。

SQLFiddle:http://sqlfiddle.com/#!6/baffd/35

设置数据:

create table sto_ov_managednode (
  object_text varchar(100),
  name varchar(100)
);

create table OV_PM_PolicyOnNode (
  nodeid varchar(100),
  policyversionid varchar(100)
);

create table OV_PM_PolicyVersion (
  policyversionid varchar(100),
  policyid varchar(100)
);

create table OV_PM_Policy (
  name varchar(100),
  PolicyId varchar(100)
);

create table OV_PM_PolicyGroupAssignment (
  PolicyId varchar(100),
  GroupId varchar(100)
);

insert into sto_ov_managednode values ('Caption ---Server1"---AgentBinaryFormatId---OsVersionId---18--','node1');
insert into sto_ov_managednode values ('Caption ---Server2"---AgentBinaryFormatId---OsVersionId---18--','node2');

insert into OV_PM_PolicyOnNode values ('node1','policyversion1');
insert into OV_PM_PolicyOnNode values ('node1','policyversion2');
insert into OV_PM_PolicyOnNode values ('node2','policyversion1');

insert into OV_PM_PolicyVersion values ('policyversion1','policyid1');
insert into OV_PM_PolicyVersion values ('policyversion2','policyid2');

insert into OV_PM_Policy values ('policy A','policyid1');
insert into OV_PM_Policy values ('policy B','policyid1');
insert into OV_PM_Policy values ('policy C','policyid2');

insert into OV_PM_PolicyGroupAssignment values ('policyid1','18681abc-097d-41cd-9782-e28d9a9f5fc4');
insert into OV_PM_PolicyGroupAssignment values ('policyid2','18681abc-097d-41cd-9782-e28d9a9f5fc4');

查询:

    select MN.name as nodeName, P.name as policyName
    FROM OV_PM_PolicyGroupAssignment PGA
    left join OV_PM_Policy P on PGA.PolicyId = P.PolicyId
    left join OV_PM_PolicyVersion PV on P.PolicyId = PV.policyid
    cross join sto_ov_managednode MN

 where PGA.GroupId = 'Base Windows'
    except
    select MN.name as nodeName, P.name as policyName
    from sto_ov_managednode MN
    left join OV_PM_PolicyOnNode PON on pon.nodeid = mn.name
    left join OV_PM_PolicyVersion PV on PV.policyversionid = pon.policyversionid
    left join OV_PM_Policy P on P.PolicyId = pv.policyid
    left join OV_PM_PolicyGroupAssignment PGA on P.PolicyId = PGA.PolicyId
    where PGA.GroupId = 'Base Windows'
    order by nodeName, policyName;

查询的顶部获取策略组的所有策略,并与节点进行交叉连接,以列出每个节点的一个策略,无论策略是否存在。然后我使用EXCEPT删除现有的节点策略。

结果:

nodeName    policyName
node2       policy C