2013-05-13 29 views
5

Bu soruyu nasıl ifade edeceğinizden emin değilim, ancak birleştirilmiş sorguyu birden çok satıra uygulamak istiyorum. Umarım bir örnek bunu daha kolay hale getirmelidir. yılların sayısı onlar oynuyorum yaniSQL'de toplu birleştirilmiş ve toplu olmayan sorgu

player | year | games 
------------------------- 
ausmubr01 | 2006 | 139 
ausmubr01 | 2007 | 117 
bondsba01 | 2006 | 130 
bondsba01 | 2007 | 126 
stairma01 | 2006 | 26 
stairma01 | 2006 | 77 
stairma01 | 2006 | 14 
stairma01 | 2007 | 125 

Ve her yıl her oyuncu için, onların "kariyer yılı" hesaplamak istiyorum: Aşağıdaki veriler var varsayarsak

player | year | games | cyear 
-------------------------------- 
ausmubr01 | 2006 | 139 | 1 
ausmubr01 | 2007 | 117 | 2 
bondsba01 | 2006 | 130 | 1 
bondsba01 | 2007 | 126 | 2 
stairma01 | 2006 | 26 | 1 
stairma01 | 2006 | 77 | 2 
stairma01 | 2006 | 14 | 3 
stairma01 | 2007 | 125 | 4 

SELECT player, year, games, year - min(year) + 1 as cyear FROM baseball GROUP by player olarak bu dönüşümü ifade etmek doğal olacaktır fakat agrega sorgular için kuralların ifadesi sadece her grup için bir kere değerlendirilir:

player | year | games | cyear 
-------------------------------- 
ausmubr01 | 2006 | 139 | 1 
bondsba01 | 2006 | 130 | 1 
stairma01 | 2006 | 26 | 1 

Bunu üstesinden nasıl genel olarak problem (ör. sadece bu durum için değil, ancak varolan bir sütunu ve bir toplu işlevle hesaplanan tek bir grup başına sayıyı birleştiren bir aritmetik işlem gerçekleştirmek istediğimde)?

+1

uygun etiketi (Oracle, SQL Server, MySQL, vs) ilave ederek hedeflediği RDBMS'yi belirtiniz dil veya ürünün yararlanmak cevaplar olabilir evrensel olarak desteklenmeyen özellikler Ayrıca, belirli bir RDBMS ile etiketleyerek, sorunuzu yanıtlamak için daha uygun insanlardan dikkatini çekebilir – Taryn

+1

@blue ayaklar Belirli bir RDBMS'ye değil, geniş ölçüde geçerli olan cevaplarla ilgileniyorum. – hadley

cevap

4

Sen kariyer yıl için ROW_NUMBER kullanabilirsiniz:

SELECT player, year, games, 
     cyear = ROW_NUMBER() OVER (PARTITION BY player ORDER BY year), 
     gamesPerMax = 1.0 * games/MAX(games) OVER (PARTITION BY player) 
FROM dbo.TableName 

Demo

güçlü OVER clause göz at.

+0

Teşekkürler - bu özel durum için yardımcı olur, ancak genel olarak değil (ör., 'Games/max (games) ' – hadley

+0

@hadley: Sonra' games/MAX (games) OVER ... 'kullanın, cevabımı düzenledim –

+0

- prototipleme için kullandığım RDMS tarafından desteklenmiyor (sqlite) ama postgresql'in de onu desteklediğini görüyorum. – hadley

0

Sadece

GROUP BY player, year 
3

Bir basit yöntem toplu bir sorgu olarak her oyuncunun başlangıç ​​yılı hesaplamak ve orijinal ile veri katılmaktır istenilen sahada ... ve toplamı birden grup kullanın. "Temelli dizisi" Bu tür sorguları

WITH tmp as (
    select player, min(year) as minyear 
    from table 
    group by player 
); 

select t.*, t.year - t.minyear + 1 as cyear 
from table as t, tmp 
where t.player = tmp.player; 
1

siz ya ÜZERİNDEN o zaman ... gerçek bir veritabanı olsun İLE yoksa . Bu gerçekleşmediği takdirde :(kümesi tabanlı lisan ile ifade genellikle zor olan, . Eğer bir alt sorgu ile yapabilirsiniz:

SELECT t.*, t.year - subtable.minyear + 1 AS cyear 
FROM table AS t 
JOIN (
    select player, min(year) as minyear 
    from table 
    group by player 
) AS SubTable 
ON T.player = SubTable.player