2014-01-25 68 views
0

這裏經過綜合屬性的最大值獲取SQL元組是架構:包含分組

ACTOR (id, name) 
PLAY (id, name, year) 
CASTS (pid, aid, character) 

的問題是: 查找具有最大的投戲劇(演員不同),並返回標題和演那些戲劇的大小。

這是SQL查詢,我至今:

select mm.id, mm.name, count(distinct a.id) as numOfActors 
from actor a 
join casts c on c.pid = a.id 
join play mm on mm.id = c.aid 
group by mm.id, mm.name; 

從該查詢返回的每個元組都包含不同的玩法,顯示其ID,名稱,且將其擁有的數量。但是從那裏開始,我很難將它作爲一個子查詢適配在外部查詢中,這將允許我只提取具有最大numofActors值的元組(如果最大值爲100,那麼只有那些會返回都有100名演員)。

是的,這是那些「家庭作業」類型的問題之一,但我也在尋找概念理解(本質上,在完成分組之後提取包含某個聚集屬性的最大值的元組)。由於可能有多個值最大的元組,所以降序排列並選擇頂部元組不起作用。

+1

什麼數據庫您使用的? –

+0

我正在使用SQL Server – ShadowCrossZero

回答

1

這裏是SQL Server的方法:

select acp.* 
from (select p.id, p.name, count(distinct a.id) as numOfActors, 
      max(count(distinct a.id)) over() as maxcnt 
     from actor a join 
      casts c 
      on c.pid = a.id join 
      play p 
      on p.id = c.aid 
     group by p.id, p.name 
    ) acp 
where numOfActors = maxnt; 

表達max(count(distinct a.id)) over (partition by partition by p.id)是窗函數的一個例子。它正在計算一組行的最大值。由於()爲空(不存在partition by子句),因此它會將相同的最大值分配給所有行中的新列。

這是什麼值?它是計算值count(distinct a.id)) over (partition by partition by p.id)的最大值。你想找到所有有這個演員數量的劇本,所以外部查詢只是選擇這些。

,因爲你不能在where子句中使用窗口函數需要一個子查詢。

編輯:

with acp as (
     select p.id, p.name, count(distinct a.id) as numOfActors 
     from actor a join 
      casts c 
      on c.pid = a.id join 
      play p 
      on p.id = c.aid 
     group by p.id, p.name 
    ) 
select acp.* 
from acp join 
    (select p.id, max(numOfActors) as maxnoa 
     from acp 
     group by p.id 
    ) acpm 
    on acp.id = acpm.id and acp.numOfActors = acpm.maxnoa; 
+0

沒有使用over()會有可能嗎? – ShadowCrossZero

+0

是的,但這需要將子查詢連接回您的表達式或公用表表達式。這是編寫查詢的最簡單且通常最有效的方式。 –

+0

您能否向我展示非over()版本? – ShadowCrossZero