TOP,SUM SQL语句

时间:2012-01-20 15:39:17

标签: sql sql-server-2005

我有一个名为RPT的表,其中包含以下列:

  1. CODENUMBER
  2. AXSUBGROUP
  3. ITEMSTRUCTURE
  4. UNITSSOLD
  5. DOLLARS
  6. 我需要根据TOP 20 AXSUBGROUPS以及UNITSSOLDUNITSSOLD值返回DOLLARS用户。另外,我需要返回属于前20名ITEMSTRUCTURES的{​​{1}}(由codenumber加入),以及他们的AXSUBGROUPSUNITSSOLD

    由于我需要按DOLLARS进行分组,然后AXSUBGROUP进行分组,但ITEMSTRUCTUREITEMSTRUCTURE aXSUBGROUP相关联,我不确定要查询此方法。 {1}}。

    我很感激您能给予的任何帮助。

    谢谢。

    EDIT 为了更好地说明我的需求:

    1. BAR - 10,000
      • BAR 2 oz - 5,000
      • BAR 1盎司 - 5,000
    2. GIFT BOX - 8,000
      • TRUFFLE BOX - 5,000
      • ACRYLIC BOX - 3,000
    3. ...

      这是表格中的示例数据(抱歉 - 无法弄清楚如何格式化表格......)

      CODENUMBER

      ... 如果它有帮助,最初这是2个表 - RPT(CodeNumber,UnitsSold,Dollars)和FLEX(CodeNumber,AxSubGroup,ItemStructure)。

4 个答案:

答案 0 :(得分:3)

看起来好像是ROW_NUMBER救援!

SELECT CODENUMBER
    , AXSUBGROUP
    , ITEMSTRUCTURE
    , UNITSSOLD
    , DOLLARS
FROM
(
    SELECT CODENUMBER
        , AXSUBGROUP
        , ITEMSTRUCTURE
        , UNITSSOLD
        , DOLLARS
        , ROW_NUMBER() OVER (PARTITION BY AXSUBGROUP ORDER BY UNITSSOLD DESC) AS r
    FROM RPT
) a
WHERE r <= 20

答案 1 :(得分:2)

SELECT 
      RPT.CodeNumber
    , RPT.AxSubgroup
    , RPT.ItemStructure
    , RPT.UnitsSold
    , RPT.Dollars
    , grp.TotalUnitsSold
FROM 
      RPT
  JOIN
      ( SELECT TOP 20 
              AxSubgroup
            , SUM(UnitsSold) AS TotalUnitsSold
        FROM
              RPT 
        GROUP BY
              AxSubgroup
        ORDER BY
              TotalUnitsSold DESC
      ) AS grp
    ON 
      grp.AxSubgroup = RPT.AxSubgroup
ORDER BY
      RPT.AxSubgroup 

答案 2 :(得分:1)

需要一个与样本源数据匹配的预期输出的更好示例。这个问题仍然存在很多含糊之处。但这是另一个刺:

将样本源数据与4个“AxSubGroup”项目(“Bar”,“Tin”,Truffle“,”Box“)一起使用,此解决方案限制在前3个AxSubGroup(而不是前20个)。

“top”子查询为每个“AxSubGroup”求和“UnitsSold”,按降序排序,为它们编号,并抓住前3个。这是最后一个条目被削掉之前的结果:

 axsubgroup | totalsold | rownum
------------+-----------+--------
 Bar        |        27 |      1
 Box        |        19 |      2
 Truffle    |        10 |      3
 Tin        |         5 |      4
(4 rows)

然后将此集合连接回原始RPT表,以获取每个这些顶级axsubgroup项目的详细信息。

CREATE TABLE rpt(CodeNumber varchar(6), UnitsSold int, Dollars int, AxSubGroup varchar(32), ItemStructure varchar(32));

INSERT INTO rpt VALUES('ABC123', 9, 500, 'Bar', '1 oz');
INSERT INTO rpt VALUES('ABC456', 9, 800, 'Bar', '2 oz');
INSERT INTO rpt VALUES('ABC789', 9, 500, 'Bar', '3 oz');
INSERT INTO rpt VALUES('DEF123', 3, 200, 'Tin', 'Round');
INSERT INTO rpt VALUES('DEF456', 2, 200, 'Tin', 'Rectangular');
INSERT INTO rpt VALUES('GHI123', 1, 200, 'Truffle', 'Luxe');
INSERT INTO rpt VALUES('GHI456', 5, 100, 'Truffle', 'Executive');
INSERT INTO rpt VALUES('GHI789', 4, 200, 'Truffle', 'Eco');
INSERT INTO rpt VALUES('JKL123', 9, 500, 'Box', '2 pc');
INSERT INTO rpt VALUES('JKL456', 5, 100, 'Box', '4 pc');
INSERT INTO rpt VALUES('JKL789', 5, 100, 'Box', '8 pc');


WITH top AS (

     -- Top AxSubGroups based on UnitsSold with order number assigned, restricted to top 20
    SELECT AxSubGroup, totalSold, rowNum
      FROM (
             -- Top AxSubGroups based on UnitsSold with order number assigned
             SELECT AxSubGroup, totalSold
                   ,ROW_NUMBER() OVER (ORDER BY totalSold DESC) AS rowNum
               FROM ( 
                      -- Top AxSubGroups based on UnitsSold
                      -- (do you really want this 'UnitsSold' or rather on 'gross': 'UnitsSold' * 'Dollars'?)
                      SELECT AxSubGroup, SUM(UnitsSold) AS totalSold
                        FROM rpt r
                        GROUP BY AxSubGroup
                        ORDER by totalSold DESC
                    ) x
               ORDER BY totalSold DESC
           ) y
      WHERE rowNum <= 3
)

SELECT t.AxSubGroup, t.totalSold, r.ItemStructure, r.UnitsSold, r.Dollars
  FROM top t
      ,rpt r
  WHERE r.AxSubGroup = t.AxSubGroup;

 axsubgroup | totalsold | itemstructure | unitssold | dollars
------------+-----------+---------------+-----------+---------
 Bar        |        27 | 1 oz          |         9 |     500
 Bar        |        27 | 2 oz          |         9 |     800
 Bar        |        27 | 3 oz          |         9 |     500
 Truffle    |        10 | Luxe          |         1 |     200
 Truffle    |        10 | Executive     |         5 |     100
 Truffle    |        10 | Eco           |         4 |     200
 Box        |        19 | 2 pc          |         9 |     500
 Box        |        19 | 4 pc          |         5 |     100
 Box        |        19 | 8 pc          |         5 |     100
(9 rows)

结果的前两列是对每个成员重复的摘要/总列,而最后三列是构成总和的详细信息。

答案 3 :(得分:1)

所以看起来你需要:

  1. 计算小组总数。

  2. 按总数对组进行排名。

  3. 获取前20名UNION中排名前20位的组的详细信息。

  4. 所以也许是这样的:

    ;
    WITH RPT (CodeNumber, UnitsSold, Dollars, AxSubGroup, ItemStructure) AS (
      SELECT 'ABC123', 9, 500, 'Bar'    , '1 oz'        UNION ALL
      SELECT 'ABC456', 9, 800, 'Bar'    , '2 oz'        UNION ALL
      SELECT 'ABC789', 9, 500, 'Bar'    , '3 oz'        UNION ALL
      SELECT 'DEF123', 3, 200, 'Tin'    , 'Round'       UNION ALL
      SELECT 'DEF456', 2, 200, 'Tin'    , 'Rectangular' UNION ALL
      SELECT 'GHI123', 1, 200, 'Truffle', 'Luxe'        UNION ALL
      SELECT 'GHI456', 5, 100, 'Truffle', 'Executive'   UNION ALL
      SELECT 'GHI789', 4, 200, 'Truffle', 'Eco'         UNION ALL
      SELECT 'JKL123', 9, 500, 'Box'    , '2 pc'        UNION ALL
      SELECT 'JKL456', 5, 100, 'Box'    , '4 pc'        UNION ALL
      SELECT 'JKL789', 5, 100, 'Box'    , '8 pc'
    ),
    totals AS (
      SELECT
        *,
        TotalUnitsSold = SUM(UnitsSold) OVER (PARTITION BY AxSubGroup),
        TotalDollars   = SUM(Dollars  ) OVER (PARTITION BY AxSubGroup)
      FROM RPT
    ),
    ranked AS (
      SELECT
        *,
        rnk = DENSE_RANK() OVER (ORDER BY TotalDollars DESC, AxSubGroup)
      FROM totals
    )
    
    SELECT
      rnk,
      AxSubGroup,
      ItemStructure,
      UnitsSold,
      Dollars
    FROM ranked
    WHERE rnk <= 3
    
    UNION ALL
    
    SELECT DISTINCT
      rnk,
      AxSubGroup,
      NULL,
      TotalUnitsSold,
      TotalDollars
    FROM ranked
    WHERE rnk <= 3
    
    ORDER BY rnk, AxSubGroup, ItemStructure
    

    结果是:

    rnk  AxSubGroup  ItemStructure  UnitsSold    Dollars
    ---  ----------  -------------  -----------  -----------
    1    Bar         NULL           27           1800
    1    Bar         1 oz           9            500
    1    Bar         2 oz           9            800
    1    Bar         3 oz           9            500
    2    Box         NULL           19           700
    2    Box         2 pc           9            500
    2    Box         4 pc           5            100
    2    Box         8 pc           5            100
    3    Truffle     NULL           10           500
    3    Truffle     Eco            4            200
    3    Truffle     Executive      5            100
    3    Truffle     Luxe           1            200