查询从子查询中查找前3个

时间:2016-10-17 11:12:06

标签: sql-server

我创建了一个查询

SELECT  Years 
        ,Months
        ,VulName
        ,Vulcount
        ,SUM(VulCount) OVER(PARTITION BY  VulId) AS  Totals 
FROM
( 
    SELECT  YEAR(outertblissues.OpenDt) AS Years 
            ,MONTH(outertblissues.OpenDt) AS Months
            ,outertblvulnerability.VulId
            ,outertblvulnerability.VulName
            ,COUNT(outertblvulnerability.VulId) Vulcount
    FROM    tbl_apptestdetails AS outertblapptestdetails 
            INNER JOIN tbl_applicationlist AS outertblapplicationlist 
                ON outertblapptestdetails.appid=outertblapplicationlist.appid 
            INNER JOIN tbl_bu AS outertblbu 
                ON outertblbu.buid=outertblapplicationlist.buid 
            INNER JOIN tbl_Issues AS outertblissues 
                ON outertblapptestdetails.testdetailid=outertblissues.testdetailid 
                   AND outertblissues.Status NOT IN('1','4')  
            INNER JOIN tbl_vulnerability AS outertblvulnerability 
                ON outertblissues.VulId=outertblvulnerability.VulId
    GROUP   BY YEAR(outertblissues.OpenDt)
               ,MONTH(outertblissues.OpenDt)
               ,outertblvulnerability.VulId
               ,outertblvulnerability.VulName
) a
ORDER BY Totals DESC

给出了输出 enter image description here

我只想挑选所有那些位于最大顶部(3)Totals的记录,并且要记住的一件事是,如果多个VulName的Totals相同,那么结果应该只包含不同的前3个VulName,Totals是我的最后一栏

3 个答案:

答案 0 :(得分:0)

这是一个选项:

WITH    CTE
          AS (
              SELECT
                c.Years
              , c.Months
              , c.VulName
              , c.Vulcount
              , SUM(c.Vulcount) OVER (PARTITION BY VulId) AS Totals
              FROM
                (
                 SELECT
                    YEAR(i.OpenDt) AS Years
                  , MONTH(i.OpenDt) AS Months
                  , v.VulId
                  , v.VulName
                  , COUNT(v.VulId) Vulcount
                 FROM
                    tbl_apptestdetails AS atd
                 INNER JOIN tbl_applicationlist AS al
                    ON atd.appid = al.appid
                 INNER JOIN tbl_bu AS bu
                    ON bu.buid = al.buid
                 INNER JOIN tbl_Issues AS i
                    ON atd.testdetailid = i.testdetailid
                       AND i.Status NOT IN ('1', '4')
                 INNER JOIN tbl_vulnerability AS v
                    ON i.VulId = v.VulId
                 GROUP BY
                    YEAR(i.OpenDt)
                  , MONTH(i.OpenDt)
                  , v.VulId
                  , v.VulName
                ) c
             )
    SELECT
        *
    FROM
        CTE c
    WHERE
        c.Totals IN (SELECT DISTINCT TOP 3
                        Totals
                     FROM
                        CTE
                     ORDER BY
                        Totals DESC);

已修改:已移动订单以修复查询。

答案 1 :(得分:0)

根据有关要求的新信息,我建议以下查询:

WITH    CTE
          AS (
                 SELECT
                    YEAR(i.OpenDt) AS Years
                  , MONTH(i.OpenDt) AS Months
                  , v.VulId
                  , v.VulName
                  , COUNT(v.VulId) AS Vulcount
                  , SUM(COUNT(v.VulId)) OVER (PARTITION BY VulId) AS Totals
                 FROM
                    tbl_apptestdetails AS atd
                 INNER JOIN tbl_applicationlist AS al
                    ON atd.appid = al.appid
                 INNER JOIN tbl_bu AS bu
                    ON bu.buid = al.buid
                 INNER JOIN tbl_Issues AS i
                    ON atd.testdetailid = i.testdetailid
                       AND i.Status NOT IN ('1', '4')
                 INNER JOIN tbl_vulnerability AS v
                    ON i.VulId = v.VulId
                 GROUP BY
                    YEAR(i.OpenDt)
                  , MONTH(i.OpenDt)
                  , v.VulId
                  , v.VulName
             ) ,
        cte2
          AS (
              SELECT
                c.Years
              , c.Months
              , c.Vulcount
              , c.VulName
              , c.Totals
              , ROW_NUMBER() OVER (PARTITION BY c.VulId ORDER BY C.Totals DESC) AS RowNum
              FROM
                CTE c
             )
    SELECT
        c.Years
      , c.Months
      , c.VulName
      , c.Vulcount
      , c.Totals
    FROM
        cte2 c
    WHERE
        c.RowNum <=3
    ORDER BY
        c.Totals;

答案 2 :(得分:0)

这可能对您有用,将您的第一个查询包装在cte中(删除order by子句),然后使用另一个cte来建立您感兴趣的前三行,然后通过内部过滤您的最终选择加入;

WITH cte_Select AS
(
    SELECT  Years 
            ,Months
            ,VulName
            ,Vulcount
            ,SUM(VulCount) OVER(PARTITION BY  VulId) AS  Totals 
    FROM
    ( 
        SELECT  YEAR(outertblissues.OpenDt) AS Years 
                ,MONTH(outertblissues.OpenDt) AS Months
                ,outertblvulnerability.VulId
                ,outertblvulnerability.VulName
                ,COUNT(outertblvulnerability.VulId) Vulcount
        FROM    tbl_apptestdetails AS outertblapptestdetails 
                INNER JOIN tbl_applicationlist AS outertblapplicationlist 
                    ON outertblapptestdetails.appid=outertblapplicationlist.appid 
                INNER JOIN tbl_bu AS outertblbu 
                    ON outertblbu.buid=outertblapplicationlist.buid 
                INNER JOIN tbl_Issues AS outertblissues 
                    ON outertblapptestdetails.testdetailid=outertblissues.testdetailid 
                       AND outertblissues.Status NOT IN('1','4')  
                INNER JOIN tbl_vulnerability AS outertblvulnerability 
                    ON outertblissues.VulId=outertblvulnerability.VulId
        GROUP   BY YEAR(outertblissues.OpenDt)
                   ,MONTH(outertblissues.OpenDt)
                   ,outertblvulnerability.VulId
                   ,outertblvulnerability.VulName
    ) a            
)

, cte_Top3_Vulcount as
(

    SELECT TOP (3)
        Totals
    FROM cte_Select
    GROUP BY Totals
    ORDER BY Totals DESC
)

SELECT  s.Years 
        ,s.Months
        ,s.VulName
        ,s.Vulcount
        ,s.Totals 
FROM cte_Select s
INNER JOIN cte_Top3_Vulcount t3
    on t3.[Totals] = s.[Totals]

实际上,一小时前该要求被澄清为;

  

Vulname

排序的前三个唯一Totals

在此基础上,将cte_Top3_Vulcount的内容替换为以下内容;

    SELECT TOP (3)
        VulName
    FROM cte_Select
    GROUP BY VulName
    ORDER BY max(Totals) DESC

整个查询将成为;

WITH cte_Select AS
(
    SELECT  Years 
            ,Months
            ,VulName
            ,Vulcount
            ,SUM(VulCount) OVER(PARTITION BY  VulId) AS  Totals 
    FROM
    ( 
        SELECT  YEAR(outertblissues.OpenDt) AS Years 
                ,MONTH(outertblissues.OpenDt) AS Months
                ,outertblvulnerability.VulId
                ,outertblvulnerability.VulName
                ,COUNT(outertblvulnerability.VulId) Vulcount
        FROM    tbl_apptestdetails AS outertblapptestdetails 
                INNER JOIN tbl_applicationlist AS outertblapplicationlist 
                    ON outertblapptestdetails.appid=outertblapplicationlist.appid 
                INNER JOIN tbl_bu AS outertblbu 
                    ON outertblbu.buid=outertblapplicationlist.buid 
                INNER JOIN tbl_Issues AS outertblissues 
                    ON outertblapptestdetails.testdetailid=outertblissues.testdetailid 
                       AND outertblissues.Status NOT IN('1','4')  
                INNER JOIN tbl_vulnerability AS outertblvulnerability 
                    ON outertblissues.VulId=outertblvulnerability.VulId
        GROUP   BY YEAR(outertblissues.OpenDt)
                   ,MONTH(outertblissues.OpenDt)
                   ,outertblvulnerability.VulId
                   ,outertblvulnerability.VulName
    ) a            
)

, cte_Top3_VulName as
(
    SELECT TOP (3)
        VulName
    FROM cte_Select
    GROUP BY VulName
    ORDER BY max(Totals) DESC
)

SELECT  s.Years 
        ,s.Months
        ,s.VulName
        ,s.Vulcount
        ,s.Totals 
FROM cte_Select s
INNER JOIN cte_Top3_VulName t3
    on t3.VulName = s.VulName