我想在PostgreSQL中只显示总行数的80%

时间:2013-11-13 06:50:51

标签: sql postgresql group-by

    GroupNo   Commodity    AuctionRate    Quantity  Mandi Grade
     1         8            25000          5000      2      1
     1         8            5555           5000      2      1
     1         8            6000           2000      2      1
     2         8            4000           500       2      3
     1         8            6000           500       2      1
     1         8            5000           500       2      1
     1         8            77777          500       2      1
     1         8            22222          200       2      1
     1         8            55555          100       2      1
     1         8            100            100       2      1

在这里,我使用以下查询

获取此表
    select 

    dense_rank() over (order by AD."Commodity",AD."Mandi",AD."Grade") as "GroupNo"
    ,AD."Commodity"
    ,AD."AuctionRate"
    ,AD."Quntity"
    ,AD."Mandi"
    ,AD."Grade"


    from "AuctionDetails" AD

    order by  AD."Quntity" desc

现在每个记录组都有一个“GroupNo”。

现在我想对只有80%记录的“AuctionRate”和“Quantity”进行总结,这些记录具有相同的组NUmber

在我们的示例中,有9行,其中groupNo为“1”,只有1行,groupNo为“2”。

现在,9%的80%约为7,而1的80%约为1。

所以我想要只有前7行的“AuctionRate”和“Quantity”的总和,其中groupno“1”和1行的总和也有groupno“2”

期望的结果如下所示

    GroupNo   Commodity    AuctionRate    Quantity  Mandi Grade
     1         8            147554         13700     2      1
     2         8            4000           500       2      3

希望你能理解我的问题。

1 个答案:

答案 0 :(得分:1)

嗯,它看起来不是很整洁,但现在是:

WITH Main AS (
  SELECT  DENSE_RANK() OVER (ORDER BY AD.Commodity, AD.Mandi, AD.Grade) AS GroupNo
        , AD.Commodity
        , AD.AuctionRate
        , AD.Quantity
        , AD.Mandi
        , AD.Grade
  FROM AuctionDetails AS AD
  ORDER BY AD.Quantity DESC
)
SELECT  q.GroupNo
      , q.Commodity AS Commodity
      , SUM(q.AuctionRate) AS AuctionRate
      , SUM(q.Quantity) AS Quantity
      , q.Mandi
      , q.Grade 
FROM
(
  SELECT  Main.*
        , ROW_NUMBER() OVER (PARTITION BY Main.GroupNo ORDER BY Main.Quantity DESC) AS RowNum
        , Counter.Total
    FROM Main
    INNER JOIN
    (
        SELECT Main.GroupNo, COUNT(*) AS Total
        FROM Main
        GROUP BY Main.GroupNo
    ) AS Counter
  ON Main.GroupNo = Counter.GroupNo
) AS q
WHERE q.RowNum <= CAST(q.Total * 0.8 AS INT)
GROUP BY q.GroupNo, q.Commodity, q.Mandi, q.Grade

由于你在PostgreSQL中没有SELECT TOP 80 PERCENT,而且,因为你需要将它四舍五入(9个中的7个和1个中的1个),所以你应该手动完成。这就是为什么有必要将表与SELECT COUNT(*)联系起来。

无法避免深度嵌套,因为您无法在ROW_NUMBER() - 子句中使用WHERE

请查看SqlFiddle了解更多详情。第一个查询显示了主要想法:我们得到组内的行号和组内元素的总数。当我们拥有它们时,我们可以发挥魔力。