SQL中的最大总和

时间:2008-11-04 00:05:59

标签: sql subquery sum max

我有一个商店列表,商店内的部门和每个部门的销售情况,如此(使用子查询中的max(sales)创建,但这在我认为不是非常重要):

toronto    baskets 500
vancouver  baskets 350
halifax    baskets 100
toronto    noodles 275
vancouver  noodles 390
halifax    noodles 120
halifax    fish    200

我想请各个商店最畅销的部门。结果应如下所示:

toronto    baskets 500
vancouver  noodles 275
halifax    fish    200

每当我使用GROUP BY时,它都会包含子查询中的所有列表。没有临时表,有没有一个很好的干净方法呢?

7 个答案:

答案 0 :(得分:4)

这适用于Sql Server(肯定是2000及以上版本)

SELECT a.Store, a.Department, a.Sales
FROM temp a
INNER JOIN 
(SELECT store, max(sales) as sales
FROM temp
GROUP BY Store) b
ON a.Store = b.Store AND a.Sales = b.Sales;

答案 1 :(得分:2)

这适用于Oracle,其他实现可能具有不同的分析函数语法(或完全缺少它们):

select store
     , max(department) keep(dense_rank last order by sales)
     , max(sales)
  from (
        ...query that generates your results...
       )
 group by store

答案 2 :(得分:2)

我的2个SQL 2005解决方案如下。如果两个销售数字相同,我目前可以看到的其他数据可能无法返回正确的数据。这取决于你的需求。

第一个使用Row_Number()函数,所有行都从最低销售额到最高销售额排序(然后是一些打破平局规则)。然后每个商店选择最高等级以获得结果。

您可以尝试将Partion By子句添加到Row_Number函数(请参阅BOL)和/或使用内部联接而不是“in”子句进行调查。

第二,借用Turnkey的想法,再次对它们进行排名,但按商店分区,因此我们可以选择排名第一的。 Dense_Rank可能会给两个相同的行提供相同的排名,因此如果store和department不是唯一的,它可以返回两行。使用Row_number时,该分区中的数字是唯一的。

有些事情需要注意的是,这可能会很慢,但对于大多数数据集而言比其他解决方案中的子查询要快。在该解决方案中,每行必须运行一次查询(包括排序等),这可能导致大量查询。

其他查询选择每个商店的最大销售额并以该方式返回数据,如果两个部门恰好具有相同的销售额,则返回商店的重复行。最后一个查询显示了这一点。

DECLARE @tbl as TABLE (store varchar(20), department varchar(20), sales int)

INSERT INTO @tbl VALUES ('Toronto', 'Baskets', 500)
INSERT INTO @tbl VALUES ('Toronto', 'Noodles', 500)
INSERT INTO @tbl VALUES ('Toronto', 'Fish', 300)
INSERT INTO @tbl VALUES ('Halifax', 'Fish', 300)
INSERT INTO @tbl VALUES ('Halifax', 'Baskets', 200)

-- Expect Toronto/Noodles/500 and Halifax/Fish/300

;WITH ranked AS -- Rank the rows by sales from 1 to x
(
    SELECT 
        ROW_NUMBER() OVER (ORDER BY sales, store, department) as 'rank', 
        store, department, sales
    FROM @tbl
)

SELECT store, department, sales
FROM ranked
WHERE rank in (
    SELECT max(rank) -- chose the highest ranked per store
    FROM ranked
    GROUP BY store
)

-- Another way
SELECT store, department, sales
FROM (
    SELECT 
        DENSE_RANK() OVER (PARTITION BY store ORDER BY sales desc, 
store desc, department desc) as 'rank',
        store, department, sales
    FROM @tbl
) tbl
WHERE rank = 1


-- This will bring back 2 rows for Toronto
select tbl.store, department, sales
from @tbl tbl
    join (
        select store, max(sales) as maxSales from @tbl group by store
    ) tempTable on tempTable.store = tbl.store 
           and tempTable.maxSales = tbl.sales

答案 3 :(得分:1)

这将在SQL Server中运行,截至2005年:

with data as
(select store, department, sales
from <your query>),
 maxsales as
(select store,  sales = max(sales)
from data
group by store)
select store, (select top 1 department from data where store = t.store and sales = t.sales order by [your criteria for ties]), sales
from maxsales m

我假设您只想在关系中显示1个部门,因此前1和[您的关系标准]可以区分它们。

答案 4 :(得分:0)

也许这可行。虽然没试过,但可能有更好的解决方案......

select yourTable.store, dept, sales
from yourTable
join (
  select store, max(sales) as maxSales from yourTable group by store
) tempTable on tempTable.store = yourTable.store 
           and tempTable.maxSales = yourTable.sales

答案 5 :(得分:0)

这将在没有临时表的SQL Server中起作用:

SELECT Store, Department, Sales FROM
(SELECT Store, Department, Sales,
DENSE_RANK()  OVER (PARTITION BY Store
ORDER BY Sales DESC) AS Dense_Rank
FROM Sales) A WHERE Dense_Rank = 1

WHERE“Sales”=您的原始查询

答案 6 :(得分:0)

这将有效

Select Store, Department, Sales
From yourTable A
Where Sales = (Select Max(Sales)
               From YourTable
               Where Store = A.Store)