从平均值中选择最低的2分

时间:2019-04-24 12:44:45

标签: sql sql-server tsql

我有一个结果集,每个项目有多个分数。我需要选择每个商店得分最低的2个项目。每个项目在示例中多次出现,我需要根据平均顺序进行排序。示例:

+------------+--------------+--------+
|   Store    |    Item      | Score  |
+------------+--------------+--------+
| Amsterdam  | Shirt_Black  |      6 |
| Amsterdam  | Shirt_Blue   |      8 |
| Amsterdam  | Shirt_White  |      5 |
| Amsterdam  | Pants_Black  |      3 |
| Amsterdam  | Pants_Black  |      1 |
| Amsterdam  | Socks_Blue   |      8 |
| Amsterdam  | Shirt_Black  |      1 |
| Rotterdam  | Shirt_Blue   |      5 |
| Rotterdam  | Shirt_White  |      3 |
| Rotterdam  | Pants_Black  |      7 |
| Rotterdam  | Socks_White  |      6 |
+------------+--------------+--------+

应该成为

+------------+-------------+-------+
|   Store    |    Item     | Score |
+------------+-------------+-------+
| Amsterdam  | Pants_Black |     2 |
| Amsterdam  | Shirt_Black |   3.5 | (Average is lower than lowest score)
| Rotterdam  | Shirt_White |     3 |
| Rotterdam  | Shirt_Blue  |     5 |
+------------+-------------+-------+

我尝试了分组依据和分区依据。但是它似乎还没有达到预期的效果。希望你们能给我一个正确的方向。

谢谢!

1 个答案:

答案 0 :(得分:2)

以下查询将适用于平均值计算:

SELECT Store, Item, CalcAvg AS Score 
FROM (
    SELECT Store, Item, CalcAvg, ROW_NUMBER() OVER (PARTITION BY Store ORDER BY CalcAvg ASC) AS Rn 
    FROM (
        SELECT Store, Item, CAST(AVG(CAST(Score AS DECIMAL(9,2))) AS DECIMAL(9, 2)) AS CalcAvg
        FROM TestTable
        GROUP BY Store, Item
    ) AS Q
)AS R
WHERE R.Rn <= 2;

包含示例数据的演示

DECLARE @TestTable TABLE (Store VARCHAR (20), Item VARCHAR (20), Score INT);

INSERT INTO @TestTable (Store, Item, Score) VALUES
('Amsterdam', 'Shirt_Black', 6),
('Amsterdam', 'Shirt_Blue',  8),
('Amsterdam', 'Shirt_White', 5),
('Amsterdam', 'Pants_Black', 3),
('Amsterdam', 'Pants_Black', 1),
('Amsterdam', 'Socks_Blue',  8),
('Amsterdam', 'Shirt_Black', 1),
('Rotterdam', 'Shirt_Blue',  5),
('Rotterdam', 'Shirt_White', 3),
('Rotterdam', 'Pants_Black', 7),
('Rotterdam', 'Socks_White', 6);

SELECT Store, Item, CalcAvg AS Score 
FROM (
    SELECT Store, Item, CalcAvg, ROW_NUMBER() OVER (PARTITION BY Store ORDER BY CalcAvg ASC) AS Rn 
    FROM (
        SELECT Store, Item, CAST(AVG(CAST(Score AS DECIMAL(9,2))) AS DECIMAL(9, 2)) AS CalcAvg
        FROM @TestTable
        GROUP BY Store, Item
    ) AS Q
)AS R
WHERE R.Rn <= 2;

输出:

Store       Item          Score
--------------------------------
Amsterdam   Pants_Black   2.00
Amsterdam   Shirt_Black   3.50
Rotterdam   Shirt_White   3.00
Rotterdam   Shirt_Blue    5.00