2014-08-11 3 views
0

Я работаю над запросом, который возвращает одну строку с самой высокой ценой в ней для каждого продукта.Невозможно получить строку с наибольшим значением столбца с использованием номера строки и группы по

Для примера у меня

Таблица T1

Product Price Tax Location 
Pen  10 2.25 A 
Pen  5 1.25 B 
Pen  15 1.5 A 
Board 25 5.26 A 
Board 2 NULL B 
Water 5 10 A 

Результат должен быть, как

Product Price Tax Location  
Pen  15 1.5 A 
Board 25 5.26 A 
Water 5 10 A 

Я использую row number() и group by для достижения этой цели с использованием следующих

ALTER VIEW [dbo].[InferredBestBids] 
AS 
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL 
             )) AS id , 
      product , 
      MAX(price) AS Price , 
      MIN(tax) AS Tax , 
      location 
    FROM [dbo].InferredBids_A 
    WHERE NOT (proce IS NULL 
        AND tax IS NULL 
       ) 
    GROUP BY market , 
      term 
GO 

Когда я побежал выше запрос, он бросил мне ошибку

Column 'dbo.InferredBids_A.Location' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause 

Когда я попытался сгруппировать результаты запроса по location, он дал мне неправильные результаты, возвращающих несколько строк для product в зависимости от location

+0

Указанный ResultSet Безразлично, т требуют 'MAX()' или 'GROUP BY'. Похоже, что вы хотите: «ROW_NUMBER() OVER (PARTITION по продукту ORDER BY Price DESC) AS rn' и предикат' rn = 1' в предложении WHERE. – spencer7593

ответ

1

Нет необходимости в GROUP BY, если вы правильно включили свои статьи row_number, а затем просто выберите их на основе списка. Не стесняйтесь добавлять дополнительный row_number вызов перед внешним запросом, если вам требуется его по какой-то другой причине. See the example here.

SELECT Product, Price, Tax, Location 
FROM (
    SELECT Product, Price, Tax, Location, ROW_NUMBER()OVER(PARTITION BY Product ORDER BY Price DESC) as RowID 
    FROM InferredBids_A 
) T 
WHERE RowID = 1 
1

Если вы выбираете то, что это агрегированный вы должны GROUP BY что-нибудь еще в списке выбора, который также не агрегируются:

SELECT Product, Price ,Tax, Location 
FROM (SELECT Product, Price ,Tax, Location, 
    RANK() OVER (PARTITION BY Product ORDER BY Price DESC) N 
    FROM InferredBids_A 
    WHERE Price IS NOT NULL AND Tax IS NOT NULL 
) T WHERE N = 1 

(RANK даст строки для связи, использовать ROW_NUMBER, если вы этого не сделаете заботиться о них)

1

внесении некоторые тестовые данные:

DECLARE @BestBids TABLE 
(
    Product VARCHAR(20), 
    Price INT, 
    Tax DECIMAL(10,2), 
    Location VARCHAR(10) 
) 

INSERT INTO @BestBids 
VALUES 
('Pen', 10, 2.25, 'A'), 
('Pen', 5, 1.25, 'B'), 
('Pen', 15, 1.5, 'A'), 
('Board', 25, 5.26, 'A'), 
('Board', 2, NULL, 'B'), 
('Water', 5, 10, 'A'); 

Мы получаем, чтобы наш номер строки устанавливался по самой высокой цене для каждого продукта.

SELECT * FROM 
(
    SELECT *, 
     ROW_NUMBER() OVER (PARTITION BY Product ORDER BY Price DESC) RN 
    FROM @BestBids 
) a 
WHERE RN=1 

Мы завершаем sql и просто выбираем номер первой строки. Вот результат:

Product Price Tax  Location RN 
Board 25  5.26 A   1 
Pen  15  1.50 A   1 
Water 5  10.00 A   1 
0

Вы можете использовать общее табличное выражение:

WITH cte 
      AS (SELECT product , 
         MAX(price) AS price 
       FROM  dbo.InferredBids_A 
      ) 
    SELECT product , 
      price , 
      tax , 
      location 
    FROM dbo.InferredBids_A tbl 
      INNER JOIN cte ON cte.product = tbl.product 
           AND cte.price = tbl.price 
Смежные вопросы