子查询返回多个值

时间:2014-08-04 20:35:52

标签: sql sql-server

SELECT CG.SITEID,
       CR.COLLECTIONID,
       CG.COLLECTIONNAME,
       CASE
          WHEN CR.ARCHITECTUREKEY = 5
          THEN
             N'vSMS_R_System'
          WHEN CR.ARCHITECTUREKEY = 0
          THEN
             (SELECT BASETABLENAME
                FROM DISCOVERYARCHITECTURES
                     JOIN
                     COLLECTION_RULES
                        ON DISCOVERYARCHITECTURES.DISCARCHKEY =
                              COLLECTION_RULES.ARCHITECTUREKEY
                     JOIN
                     COLLECTIONS_G
                        ON COLLECTION_RULES.COLLECTIONID =
                              COLLECTIONS_G.COLLECTIONID
               WHERE COLLECTIONS_G.SITEID = (SELECT TOP 1 SOURCECOLLECTIONID FROM VCOLLECTIONDEPENDENCYCHAIN WHERE DEPENDENTCOLLECTIONID = CG.SITEID ORDER BY LEVEL DESC))
            ELSE (SELECT DA.BASETABLENAME FROM DISCOVERYARCHITECTURES DA WHERE DA.DISCARCHKEY=CR.ARCHITECTUREKEY) END AS TABLENAME
  FROM COLLECTIONS_G CG
  JOIN COLLECTIONS_L CL ON CG.COLLECTIONID=CL.COLLECTIONID
  JOIN COLLECTION_RULES CR ON CG.COLLECTIONID=CR.COLLECTIONID
  WHERE (CG.FLAGS&4)=4 AND CL.CURRENTSTATUS!=5

我遇到上面代码的问题,围绕这行:

when cr.ArchitectureKey=0 then...

问题是子查询返回了多个值,而且我不太清楚如何反转查询以便我摆脱错误。

更糟糕的是,cr.ArchitectureKey通常会加入da.DiscArchKey,但cr.ArchitectureKey的值可能为0,da.DiscArchKey中不存在,{我直接加入这两个我丢失了数据。

修改

有关问题本身的更多信息:

这是Microsoft产品的存储过程,其中包含“错误”错误。 (可能被认为是一个功能),我试图修复。别担心,这只是在我自己的小测试服务器上。

无论如何,有一个集合的概念。所有集合必须具有父级(通过VCOLLECTIONDEPENDENCYCHAIN确定),但最高级别的集合除外,它是系统集合且无法修改。

每个集合可以有0个或更多规则,每个规则都有一个规则类型,其中规则类型的ID保存在COLLECTION_RULES上,该ID的匹配字符串保存到DISCOVERYARCHITECTURES

在大多数情况下,规则是WQL查询,规则类型由WQL查询中查询的表确定。

然而,这就是问题所在,集合也可以查询类型' include'或者'排除',这基本上迫使它借用另一个Collection的查询。因此,您可以有效地将另一个Collection的查询结果包含在您自己的Collection中,这就是查询。

COLLECTION_RULES而言,当发生这种情况时,规则类型的ID为0,这是DISCOVERYARCHITECTURES中不存在的值。

我试图修改的是,当规则类型为0时,获取并使用最高父母的规则类型(不是直接父级,因为父级也可以有一个包含规则,在这种情况下,规则类型仍然是0)。

问题在于,因为每个规则可以有多个规则类型,所以在某些情况下会返回多行。

我试图反转查询以删除SELECT并仅使用联接,但失败了因为我发现我总是需要将其加入DISCOVERYARCHITECTURES并且我没有什么可以加入它的规则type = 0。

EDIT2

示例数据:

Collections_G

Collections_G

Collections_L

Collections_L

Collection_Rules

Collection_Rules

DiscoveryArchitectures

DiscoveryArchitectures

vCollectionDependencyChain

vCollectionDependencyChain

原始查询和原始结果

SELECT cg.SiteID,    
         CASE 
             WHEN da.DiscArchKey=5 
             THEN N'vSMS_R_System' 
             ELSE da.BaseTableName END AS TableName 
    FROM Collections_G cg   
    JOIN Collections_L cl ON cg.CollectionID=cl.CollectionID 
    JOIN Collection_Rules cr ON cg.CollectionID=cr.CollectionID   
    JOIN DiscoveryArchitectures da ON cr.ArchitectureKey=da.DiscArchKey   
    WHERE (cg.Flags&4)=4 AND cl.CurrentStatus!=5

Original Results

从上面的结果图片中可以看出,某些集合多次出现但具有不同的TableNames。这是因为每个集合都有几个规则,每个规则都有一个cr.ArchitectureKey

此外,更重要的是,集合PS10000BPS10000C不会显示,因为cr.ArchitectureKey = 0da.DiscArchKey中不存在的值cr.ArchitectureKey

我的目标是出现有cr.ArchitectureKey的集合,但我需要为其分配da.DiscArchKey

我的想法(虽然有点缺陷,但是不知道足够的SQL以使其变得更好,所以如果有人可以提供帮助,那么也会受到赞赏)就是使用DiscArchKeys来自顶级父母。但是顶级父级可以有多个cr.ReferencedCollectionID,这就是造成问题的原因。

如上所述,让顶级父级有点缺陷,理想情况下我会获得顶级PS10000B。换句话说,如果cr.ReferencedCollectionID的{​​{1}} PS10000CPS10000C的{​​{1}} cr.ReferencedCollectionIDSMS00002的{​​{1}}没有SMS00002然后cr.ReferencedCollectionID是顶级SMS00002cr.ReferencedCollectionIDPS10000B应该PS10000C(s)等于{{{ 1}}。

1 个答案:

答案 0 :(得分:0)

请查看我想到的有线解决方案。你可能会遇到一些语法错误(很可能是第二次和第三次CTE),但这只是一个想法。

将每个案例值放在不同的CTE中,然后在最后将它们组合起来。

;WITH CTE
    AS
    (
        SELECT CG.SITEID,
               CR.COLLECTIONID,
               CG.COLLECTIONNAME
          FROM COLLECTIONS_G CG
          JOIN COLLECTIONS_L CL ON CG.COLLECTIONID=CL.COLLECTIONID
          JOIN COLLECTION_RULES CR ON CG.COLLECTIONID=CR.COLLECTIONID
          WHERE (CG.FLAGS&4)=4 AND CL.CURRENTSTATUS!=5
    ),
    ARCHITECTUREKEY5
    AS
    (
       SELECT C.SITEID,
       C.COLLECTIONID,
       C.COLLECTIONNAME,
        N'vSMS_R_System' as TABLENAME
        FROM CTE C WHERE C.ARCHITECTUREKEY = 5
    ),
    ARCHITECTUREKEY0
    AS
    (
        SELECT C.SITEID,
       C.COLLECTIONID,
       C.COLLECTIONNAME,
       BASETABLENAME as TABLENAME
        FROM CTE C,
         DISCOVERYARCHITECTURES
                JOIN
                COLLECTION_RULES
                ON DISCOVERYARCHITECTURES.DISCARCHKEY =
                        COLLECTION_RULES.ARCHITECTUREKEY
                JOIN
                COLLECTIONS_G
                ON COLLECTION_RULES.COLLECTIONID =
                        COLLECTIONS_G.COLLECTIONID
        WHERE COLLECTIONS_G.SITEID = (SELECT TOP 1 SOURCECOLLECTIONID FROM VCOLLECTIONDEPENDENCYCHAIN WHERE DEPENDENTCOLLECTIONID = C.SITEID ORDER BY LEVEL DESC))
         and C.ARCHITECTUREKEY = 0
    ),
    ARCHITECTUREKEYOTHER
    AS
    (
        SELECT C.SITEID,
       C.COLLECTIONID,
       C.COLLECTIONNAME,
       DA.BASETABLENAME as TABLENAME
       FROM DISCOVERYARCHITECTURES DA, CTE C WHERE DA.DISCARCHKEY=CR.ARCHITECTUREKEY AND C.ARCHITECTUREKEY not in (0,1)
    )
    Select * from ARCHITECTUREKEY5
    UNION
    Select * from ARCHITECTUREKEY0
    UNION
    Select * from ARCHITECTUREKEYOTHER