2014-01-24 31 views
1

好吧,我完全被難住了。SQL:如何從表中選擇具有最高變化百分比的項目

我有一個表GROCERY_PRICES。

其中有GROCERY_ITEM,PRICE_IN_2012和ESTIMATED_PRICE_IN_2042的數據。

我需要編寫一個SQL SELECT語句來查找具有最高價格增長百分比的項目。然後按GROCERY_ITEM排序。

我不能在我的生活中弄清楚如何使用表中的數據來獲取在時間段內變化率最高的三個項目。

這是我的代碼,它返回我需要的所有數據,但是對於每個GROCERY_ITEM而不是具有最高變化百分比的三個項目。我知道這是310,但我不能硬編碼在這個數字。

SELECT grocery_item, 
     price_in_2012, 
     ESTIMATED_PRICE_IN_2042, 
     sum((ESTIMATED_PRICE_IN_2042 - PRICE_IN_2012)/PRICE_IN_2012) * 100 as Percent_Change 
FROM grocery_prices 
GROUP BY grocery_item, 
     price_in_2012, 
     ESTIMATED_PRICE_IN_2042 
ORDER BY grocery_item; 

我知道我需要使用子查詢,但我不知道如何去做。

謝謝。

編輯:某些樣本數據:

Sample Data

+0

你正在使用哪些DBMS(MySQL,SQL Server,Oracle,...)? – peterm

+0

您可以提供表格中的幾行樣本數據嗎?也許是我,但你的GROUP BY對我來說沒有意義 – peterm

+0

@peterm我正在使用Oracle SQL Developer,我已經標記了它,但有人顯然刪除了標記。 –

回答

3

您正在尋找這樣的事情?

SELECT grocery_item, price_in_2012, estimated_price_in_2042, percent_change 
    FROM 
(
    SELECT grocery_item, price_in_2012, estimated_price_in_2042, 
     ROUND((estimated_price_in_2042 - price_in_2012)/price_in_2012 * 100, 2) AS percent_change, 
     ROW_NUMBER() OVER (ORDER BY ABS((estimated_price_in_2042 - price_in_2012)/price_in_2012 * 100) DESC) AS rank 
    FROM grocery_prices t 
) q 
WHERE rank <= 3; 

輸出:

 
| GROCERY_ITEM | PRICE_IN_2012 | ESTIMATED_PRICE_IN_2042 | PERCENT_CHANGE | 
|--------------|---------------|-------------------------|----------------| 
|  B_001 |   0.8 |     3.28 |   310 | 
|  G_010 |    8 |     32.8 |   310 | 
|  R_003 |    4 |     16.4 |   310 | 

根據您的需求,你可能需要使用DENSE_RANK()代替ROW_NUMBER()

SELECT grocery_item, price_in_2012, estimated_price_in_2042, percent_change 
    FROM 
(
    SELECT grocery_item, price_in_2012, estimated_price_in_2042, 
     ROUND((estimated_price_in_2042 - price_in_2012)/price_in_2012 * 100, 2) AS percent_change, 
     DENSE_RANK() OVER (ORDER BY ABS((estimated_price_in_2042 - price_in_2012)/price_in_2012 * 100) DESC) AS rank 
    FROM grocery_prices t 
) q 
WHERE rank <= 3; 

輸出:

 
| GROCERY_ITEM | PRICE_IN_2012 | ESTIMATED_PRICE_IN_2042 | PERCENT_CHANGE | 
|--------------|---------------|-------------------------|----------------| 
|  B_001 |   0.8 |     3.28 |   310 | 
|  G_010 |    8 |     32.8 |   310 | 
|  R_003 |    4 |     16.4 |   310 | 
|  E_001 |   0.62 |     1.78 |   187.1 | 
|  B_002 |   2.72 |     7.36 |   170.59 | 

這裏是SQLFiddle演示

+0

是的,正是如此。哦,所以如果我想從percent_change中進行選擇,我必須先列出它,然後在我的子查詢中定義它包含的內容等等。不過,我確實有一個問題,你將如何使用percent_change列上的max函數來做到這一點?我試圖簡單地從我的百分點方程中返回最大值,而不是返回最大值,我只是獲取每個項目的值,而不是最大percent_change的三個項目。 –

+0

如果你想返回TOP N,其中N> 1,(僅在你的情況下爲TOP 3)行只用'MAX()'是不夠的。您必須通過使用+ rownum的順序或使用分析窗口函數(如ROW_NUMBER(),DENSE_RANK(),RANK()或通過使用與COUNT()相關的子查詢來使用排名。 – peterm

+0

所以沒有辦法動態地做到這一點,所以無論有多少最大值,你只能得到那些? –

0
select * 
from im_employees a 
where (select count(distinct employee_id) from im_employees where    employee_id>=a.employee_id)<=3; 

此選擇頂部3行,最大EMPLOYEE_ID從im_employees表我。

我認爲這會幫助你!

+0

的全部內容put percent_change而不是employee_id –

0

嘗試了這一點

select ROCERY_ITEM,PRICE_IN_2012,ESTIMATED_PRICE_IN_2042,round((cast(ESTIMATED_PRICE_IN_2042-PRICE_IN_2012 as numeric)/PRICE_IN_2012)*100,3)||'%' from GROCERY_PRICES order by round((cast(ESTIMATED_PRICE_IN_2042-PRICE_IN_2012 as numeric)/PRICE_IN_2012)*100,3) desc limit 3; 
PostgreSQL中

在Oracle

select rownum,ROCERY_ITEM,PRICE_IN_2012,ESTIMATED_PRICE_IN_2042,round(((ESTIMATED_PRICE_IN_2042-PRICE_IN_2012)/PRICE_IN_2012)*100,3)||'%' from GROCERY_PRICES where rownum < 4 order by round((cast(ESTIMATED_PRICE_IN_2042-PRICE_IN_2012 as numeric)/PRICE_IN_2012)*100,3) desc; 
1

前3項有提價的比例最高

SELECT GROCERY_ITEM,PRICE_IN_2012,ESTIMATED_PRICE_IN_2042, 
ROUND(((`ESTIMATED_PRICE_IN_2042` - `PRICE_IN_2012`)/PRICE_IN_2012) * 100) AS Percent_Change 
FROM grocery_prices AS itm 
GROUP BY GROCERY_ITEM 
ORDER BY Percent_Change DESC LIMIT 3 

SQL Fiddle

希望這可以幫助您!

+0

OP是使用Oracle,而不是MySQL – peterm

+0

對不起,我認爲這是在MySQL :( –

相關問題