SQL

2011-12-15 21 views
5

'daki başka bir sütundan bir değere eşit veya daha büyük bir değere sahip satır sayısını sayma İki sütunlu bir tablom var: bir çift kimlik ve bu çifti için bir dizi "işareti". x işaretleri veya x değerlerinin her biri için daha fazla olan çiftlerin sayısını listeleyen bir sonucu istiyorum. Yani benim girişi gibi görünür:SQL

 
| couple_id | num_marks | 
|-----------+-----------| 
|   9 |   7 | 
|   6 |   6 | 
|   8 |   6 | 
|   2 |   5 | 
|   3 |   4 | 
|   5 |   4 | 
|   1 |   3 | 
|   4 |   3 | 
|  10 |   2 | 
|   7 |   1 | 

Ve sonuç almak istiyorum:

 
| num_marks | num_couples | 
|-----------+-------------| 
|   7 | 1   | 
|   6 | 3   | 
|   5 | 4   | 
|   4 | 6   | 
|   3 | 8   | 
|   2 | 9   | 
|   1 | 10   | 

yani Orada 7 veya daha fazla işareti ile 3 çift, 6 veya daha fazla işareti ile 3 çiftler, 5 veya daha fazla işareti ile çiftler, 4 , vb için bir sorgu ile gelebildim ben tam olarak çiftlerin sayısını döndürmekn işaretleri:

SELECT num_marks, 
     count(couple_id) AS num_couples 
    FROM table_name 
    GROUP BY num_marks 
    ORDER BY num_marks DESC; 

verir:

 
| num_marks | num_couples | 
|-----------+-------------| 
|   7 |   1 | 
|   6 |   2 | 
|   5 |   1 | 
|   4 |   2 | 
|   3 |   2 | 
|   2 |   1 | 
|   1 |   1 | 

Ie Orada 7 işaretleri, 6 işaretli 2 çift, 5 ile 1, 1 çift vardı orada her satırın değerini yukarıdaki olanlar ile etkili bir şekilde toplamak için uygun bir yol var mı? Uygulama düzeyinde yapabilirim, ama gerçekten veritabanına ait olan gibi bir şey gibi görünüyor.

cevap

5

Bu özellikle verimli olmayabilir ama işi olmalıdır:

SELECT t1.num_marks,  
    (SELECT count(t2.couple_id) 
    FROM table_name t2 
    WHERE t2.num_marks >= t1.num_marks 
    ) AS num_couples 
FROM table_name t1 
GROUP BY t1.num_marks 
ORDER BY t1.num_marks DESC; 

Düzenleme: Sen den seçeneğini bir sub query kullanabilirsiniz nerede, grup tarafından bir sorgulamanın maddeleri olan ve eğer ana/dış 'sorgu'ya başvurursanız, her satırın alt sorgusunu değerlendirir, daha sonra correlated subquery olarak bilinir. (Bu nedenle, performansla ilgili uyarılar)

Damien'ın cevabına göre, bir CTE-CTE kullanmanız da okunabilirliği artırabilir ve aynı zamanda özyineleme ve kendiliğinden birleşmeyi çok daha kolay bir IMO yapabilir. Çoğu SQL'de AFAIK alt sorguları desteklenmektedir. her bir sonuç alıyor nerede

+0

Bu harika bir şey! SELECT işlevinin sütun olarak olabileceğini bilmiyordum. Örneğin, üzerinde çalışacak olan standart SQL mi? SQLite ve Postgres? Ayrıca, 'table_name' aslında bir masa değil, kendi başına büyük bir honking 'SELECT'; Bu şeyleri kırar mı? – haxney

+1

@haxney - Düzenledim - evet, tablonun adını başka bir sorgu ile değiştirebilirsiniz, dış seçimlerde kullanmak için takma ad vermeniz gerekecek. – StuartLC

4

Daha sonra sadece bu rütbe üzerine bağladılar sonuç sayısını ekleyin çalışmak RANK() işlevini kullanabilirsiniz:

create table #T (couple_id int,num_marks int) 
insert into #T (couple_id,num_marks) 
select 9 ,   7 union all 
select 6 ,   6 union all 
select 8 ,   6 union all 
select 2 ,   5 union all 
select 3 ,   4 union all 
select 5 ,   4 union all 
select 1 ,   3 union all 
select 4 ,   3 union all 
select 10 ,   2 union all 
select 7 ,   1 

;with Ranked as (
    select num_marks,RANK() OVER (ORDER BY num_marks desc) as rk from #T 
) 
select num_marks,rk + COUNT(*) -1 as Result from Ranked 
group by num_marks,rk 

verir:

num_marks Result 
----------- -------------------- 
7   1 
6   3 
5   4 
4   6 
3   8 
2   9 
1   10 

(7 row(s) affected) 

(Tabii ki, Belirli bir sırada sonuçlara ihtiyacınız varsa, bir ORDER BY maddesini eklemeyi unutmayın - yukarıdaki sipariş sadece mutlu bir kazadır)