2017-03-08 1 views
2

Bitte beachten Sie, diese Tabelle:Get Interval Prozentsatz

FileName   FileSize 
---------------------------- 
1     33 
2     198 
3     10 
4     127 
5     85 
6     23 
7     105 
8     158 
9     78 
10     90 

und ich möchte so dieses Ergebnis erstellen:

FileSize    Percentage 
-------------------------------- 
1-50     30% 
50-150     50% 
150-200     20% 

Wie ich group by kann und Anteil an Intervallen basierend schaffen?

Dank

Antwort

2

Für eine Abfrage, ohne dass Sie Grenzen Tabelle eine Tabelle Inline erstellen können VALUES Konstruktor wie mit unter

select DISTINCT 
CAST(I.LowNumber as VARCHAR) + ' - '+ CAST(I.HighNumber as VARCHAR) as FileSize, 
COUNT(*) OVER (PARTITION BY lowNumber,HighNumber ORDER By lowNumber) * 100.00 /COUNT(*) OVER (ORDER BY (SELECT 1)) as percentage 
from TblFile F 
join (values (1, 50),(50, 150),(150, 200)) as I(LowNumber, highNumber) 
on F.FileSize >=I.LowNumber and F.FileSize<I.HighNumber 
Order By I.LowNumber 

Ihre Abfrage wie

select DISTINCT 
CAST(I.LowNumber as VARCHAR) + ' - '+ CAST(I.HighNumber as VARCHAR) as FileSize, 
COUNT(*) OVER (PARTITION BY lowNumber,HighNumber ORDER By lowNumber) * 100.00 /COUNT(*) OVER (ORDER BY (SELECT 1)) as percentage 
from TblFile F 
join TblInterval I 
on F.FileSize >=I.LowNumber and F.FileSize<I.HighNumber 

Erklärung aussehen sollte:

Im Idealfall sollten Sie den satzbasierten Ansatz verwenden und die Bereichswerte in einer Tabelle speichern. Dies ermöglicht eine schnellere Verarbeitung und ermöglicht Ihnen außerdem, dass ein einzelner Bereich extern und nicht in der Prozedur begrenzt wird. Dies entspricht auch dem Dependency-Injection-Prinzip.

Für Inline-anonyme Tabellen verwenden Sie VALUES-Konstruktor. Mehr dazu bei this msdn link

Output image reference:

PS: Legen Sie Skripte für die Tabelle

--create table tblInterval (LowNumber Int, HighNumber Int) 
--insert into tblInterval values 
--(1,50),(50,150),(150,200) 

create table tblFile (fileName int,fileSize int) 
insert into tblFile values 
(1 ,33) 
,(2 ,198) 
,(3 ,10 ) 
,(4 ,127) 
,(5 ,85 ) 
,(6 ,23 ) 
,(7 ,105) 
,(8 ,158) 
,(9 ,78 ) 
,(10,90 ) 

Angenommen, Sie eine Tabelle wie haben unter

TblInterval 

LowNumber HighNumber 
    1  50 
50  150 
150  200 
+0

Gute Arbeit, aber ich möchte nicht einen Tisch für Grenzen haben. Können Sie Ihre gute Abfrage ohne Begrenzungs-Tabelle erneut schreiben? – Arian

+0

@Arian aktualisierte Antwort – DhruvJoshi

+0

Das funktioniert Dank – Arian

1

Sie case-Anweisung verwenden können, um Der Dateigrößenbereich wird dann durch die Zählung wie folgt erhalten:

select a.range as FileSize, (Count(*)* 100/(Select Count(*) From MyTable)) as Percentage 
from (
select case 
when FileSize between 1 and 50 then '1-50' 
when FileSize between 50 and 150 then '50-150' 
when FileSize between 150 and 200 then '150-200' end as range 
from MyTable) a 
group by a.range 
+0

Großartig Das funktioniert, aber das Ergebnis ist nicht sortiert und 'Order by FileSize' hat nicht funktioniert. Wie kann ich es auch sortieren ... – Arian

+0

alles, was ich denken kann, ist hinzufügen "1) 1-50, 2) 50-150" anstelle von "1-50, 50-150", da sie Zeichenfolgen sind und keine Zahlen – Pream

0

können Sie AVG verwenden zusammen mit Partition von:

select distinct 
case 
when FileSize between 1 and 50 then '1-50' 
when FileSize between 50 and 150 then '50-150' 
when FileSize between 150 and 200 then '150-200' end as range 
, avg(FileSize) OVER (PARTITION BY (select 
            case when filesize between 0 and 50 then 1 
            when filesize between 50 and 150 then 2 
            when filesize between 150 and 200 then 3 
            end)) as percentage 
from mytable 
+0

Sorry es hat mein Wunschergebnis nicht erzeugt – Arian

1
CREATE TABLE #A 
(
FILENAME INT,   FILESIZE INT 
) 
INSERT INTO #A VALUES 
(1,33), 
(2,198), 
(3,10), 
(4,127), 
(5,85), 
(6,23), 
(7,105), 
(8,158), 
(9,78), 
(10,90) 

SELECT RANGE,COUNT(*)*100/(SELECT COUNT(*) FROM #A) AS PERCENTAGE 
FROM ( 
SELECT *,CASE 
WHEN FILESIZE BETWEEN 1 AND 50 THEN '1-50' 
WHEN FILESIZE BETWEEN 50 AND 150 THEN '50-150' 
WHEN FILESIZE BETWEEN 150 AND 200 THEN '150-200' END AS RANGE 
FROM #A) A 
GROUP BY A.RANGE 
ORDER BY CASE WHEN RANGE = '1-50' THEN 1 
       WHEN RANGE ='50-150' THEN 2 
       WHEN RANGE ='150-200' THEN 3 
            END 

Ausgang

RANGE PERCENTAGE 
1-50 30 
50-150 50 
150-200 20