2014-10-19 54 views
0

我得到了這個問題。當我試圖總結國家產品的最小性能時,它不起作用。 我有2個表下面 產品:SQL:如何獲取最小數量?

ID|NAME |NaID|Qty 
------------------- 
01|Fruit|JP |50 
02|MEAT |AUS |10 
03|MANGA|JP |80 
04|BOOK |AUS |8 

NATION:

NaID |NAME 
------------------- 
AUS |Australia 
JP |Japan  

我想我的結果是這樣的:

ID|NAME |Name|minQty 
------------------- 
01|Fruit|JP |50  
04|BOOK |AUS |8 

,我用:

select p.id,p.name, p.NaID,n.name,min(P.Qty)as minQty 
from Product p,Nation n 
where p.NaID=n.NaID 
group by p.id,p.name, p.NaID,n.name,p.Qty 

一個d我得到了這個(T_T):

ID|NAME |NaID|minQty 
------------------- 
01|Fruit|JP |50 
02|MEAT |AUS |10 
03|MANGA|JP |80 
04|BOOK |AUS |8 

請問,可能soneone幫助我嗎?我在想我現在在SQL上很糟糕。

+0

您真的在使用哪種DBMS?你用很多不同的標籤來標記你的問題,答案可能取決於每個可用的功能。 – 2014-10-19 09:42:17

+1

從組中刪除p.Qty? – SMA 2014-10-19 09:45:07

+0

我正在使用SQL 2005 – Hanata 2014-10-19 09:48:20

回答

0

SQL Server 2005支持的窗口功能,這樣你就可以做這樣的事情:

select id, 
     name, 
     NaID, 
     name, 
     qty 
from (
    select p.id, 
     p.name, 
     p.NaID, 
     n.name, 
     min(P.Qty) over (partition by n.naid) as min_qty, 
     p.qty 
    from Product p 
    join Nation n on p.NaID=n.NaID 
) t 
where qty = min_qty; 

如果有一個以上的國家有相同的最低值,你會得到他們每個人。如果你不希望出現這種情況,你需要使用row_number()

select id, 
     name, 
     NaID, 
     name, 
     qty 
from (
    select p.id, 
     p.name, 
     p.NaID, 
     n.name, 
     row_number() over (partition by n.naid order by p.qty) as rn, 
     p.qty 
    from Product p 
    join Nation n on p.NaID = n.NaID 
) t 
where rn = 1; 

由於您的示例輸出僅包括NAID而不是國家的名字你並不真的需要productnation之間的連接。


(沒有名爲「SQL 2005」 DBMS產品。SQL僅僅是一個(標準)的查詢語言。你指的是DBMS產品被稱爲微軟SQL服務器或者只是SQL服務器2005)

+0

非常感謝。我做的。 – Hanata 2014-10-23 01:29:02

+0

我DID IT與下面的查詢: 選擇PID, PNAME, PNAME, min_qty 從( 選擇p.id作爲PID, p.name如PNAME, n.name作爲n名稱, 分鐘(P。 Qty, p.qty from Product p join Nation n on p.NaID = n.NaID )t 其中qty = min_qty;其中qty = min_qty; – Hanata 2014-10-23 01:29:33

+0

對不起,但我不知道如何在這個論壇上正確回答 – Hanata 2014-10-23 01:30:40

0

在Oracle中,您可以使用多種技術。您可以使用子查詢和分析函數,但最有效的方法是使用聚合函數MINFIRST

你的表:

SQL> create table nation (naid,name) 
    2 as 
    3 select 'AUS', 'Australia' from dual union all 
    4 select 'JP', 'Japan' from dual 
    5/

Table created. 

SQL> create table product (id,name,naid,qty) 
    2 as 
    3 select '01', 'Fruit', 'JP', 50 from dual union all 
    4 select '02', 'MEAT', 'AUS', 10 from dual union all 
    5 select '03', 'MANGA', 'JP', 80 from dual union all 
    6 select '04', 'BOOK', 'AUS', 8 from dual 
    7/

Table created. 

查詢:

SQL> select max(p.id) keep (dense_rank first order by p.qty) id 
    2  , max(p.name) keep (dense_rank first order by p.qty) name 
    3  , p.naid "NaID" 
    4  , n.name "Nation" 
    5  , min(p.qty) "minQty" 
    6 from product p 
    7   inner join nation n on (p.naid = n.naid) 
    8 group by p.naid 
    9  , n.name 
10/

ID NAME NaID Nation  minQty 
-- ----- ---- --------- ---------- 
01 Fruit JP Japan    50 
04 BOOK AUS Australia   8 

2 rows selected. 

既然你沒有使用甲骨文,效率較低的查詢,但可能是在所有RDBMS工作:

SQL> select p.id 
    2  , p.name 
    3  , p.naid 
    4  , n.name 
    5  , p.qty 
    6 from product p 
    7   inner join nation n on (p.naid = n.naid) 
    8 where (p.naid, p.qty) 
    9   in 
10   (select p2.naid 
11    , min(p2.qty) 
12    from product p2 
13   group by p2.naid 
14  ) 
15/

ID NAME NAID NAME    QTY 
-- ----- ---- --------- ---------- 
01 Fruit JP Japan    50 
04 BOOK AUS Australia   8 

2 rows selected. 

請注意,如果您有多個行,每個國家的最小數量相同,則所有這些行都將返回,而不是ju就像之前的「Oracle」查詢一樣。

+0

對不起,我的數據庫是SQL2005。但我會用dense_rank來嘗試。非常感謝。我仍然不確定,但我認爲它會起作用。 – Hanata 2014-10-19 10:18:30

+0

SORRY,我是新手SQL。你能幫我用SQL2005嗎? – Hanata 2014-10-19 10:30:25

+0

我試過了,但不知道如何轉換成SQL2005 – Hanata 2014-10-19 10:31:13

0
with cte as (
    select *, 
     row_number() over (partition by Nation order by qty) as [rn] 
    from product 
) 
select * from cte where [rn] = 1