1
CREATE TABLE Items
(
  ItemId INT NOT NULL,
  CategoryId INT NOT NULL,
  ItemValue INT NOT NULL
)

一个表包含项目。每个项目都属于一个类别并存储一些数值。

作为查询的结果,我希望每一行代表一个类别。应该有三列:

  • 类别编号;
  • ItemValue每个类别最高的项目的 ID ;
  • ItemValue每个类别最低的项目的 ID 。

查询的性能很重要。我使用 MS SQL Server。

4

3 回答 3

2

对于 SQL Server 2005+,您可以这样做:

;WITH CTE AS
(
    SELECT  *, 
            ROW_NUMBER() OVER(PARTITION BY CategoryId ORDER BY ItemValue DESC) MaxRN,
            ROW_NUMBER() OVER(PARTITION BY CategoryId ORDER BY ItemValue) MinRN
    FROM Items
)
SELECT  CategoryId, 
        MIN(CASE WHEN MaxRN = 1 THEN ItemId END) IdMaxValue,
        MIN(CASE WHEN MinRN = 1 THEN ItemId END) IdMinValue
FROM CTE
GROUP BY CategoryId;

这是一个小提琴,您可以在其中测试此解决方案。

于 2012-07-25T14:21:42.357 回答
1

我会尝试一个公用表表达式:

WITH CategoryHigh (High, ItemId, CategoryId) 
AS 
(
SELECT 
    ROW_NUMBER() OVER (PARTITION BY CategoryId ORDER BY ItemValue DESC) AS High,
    ItemId,
    CategoryId
FROM Items
),
CategoryLow (Low, ItemId, CategoryId) 
AS
(
SELECT 
    ROW_NUMBER() OVER (PARTITION BY CategoryId ORDER BY ItemValue) AS Low,
    ItemId,
    CategoryId
FROM Items
)
SELECT 
H.CategoryId,
L.ItemId AS LowItem,
H.ItemId AS HighItem
FROM CategoryHigh H
JOIN CategoryLow L ON H.CategoryId = L.CategoryId
WHERE H.High = 1 AND
      L.Low = 1
于 2012-07-25T14:16:34.643 回答
1

试试这个:

;with 
cte as(
    select *,ROW_NUMBER() over(partition by [CategoryId] order by [ItemValue]) rownum
    from [Items] ),
cte1 as(select [CategoryId],MIN([ItemId]) [min_ItemId]
    from cte where rownum=1
    group by [CategoryId]),
cte2 as(
    select *,ROW_NUMBER() over(partition by [CategoryId] order by [ItemValue]) rownum
    from [Items] ),
cte3 as( 
    select [CategoryId],MAX([ItemId]) [max_ItemId]
    from cte2 C1
    where rownum=(select MAX(rownum) from cte C2 where C1.[CategoryId]=C2.[CategoryId])
    group by [CategoryId])
select A.[CategoryId],A.[min_ItemId],B.[max_ItemId] 
from cte1 A join cte3 B
on A.[CategoryId]=B.[CategoryId]
于 2012-07-25T14:37:19.060 回答