0
    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”进行求和

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

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

所以我想要只有前 7 行的“AuctionRate”和“Quantity”的总和,组号为“1”,以及 1 行的总和组号为“2”

期望的结果如下所示

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

希望你能理解我的问题。

4

1 回答 1

1

Well, it doesn't look very neat, but here it is:

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

Since you don't have SELECT TOP 80 PERCENT in PostgreSQL, and, moreover, since you need to round it up (7 of 9 and 1 of 1), you should do it manually. That's why it is necessary to join table with SELECT COUNT(*) from itself.

Deep nesting can't be avoided because you can't use ROW_NUMBER() in WHERE-clause.

Please, check out SqlFiddle for more details. First query shows the main idea: we get row's number inside the group and total amount of elements inside the group. When we have them, we can do the magic.

于 2013-11-13T08:06:05.117 回答