2017-08-14 33 views
0

我正在尝试查询具有多个组的表以获得满足特定条件的每个组中10%的系统。返回符合特定条件的每个组的记录的10%

这里的数据:

create table tablename as 
select '4FH6V1' as ComputerName, 'AZ1' as Location, '3093' as Rating from dual union all 
select '0GLYQ1' as ComputerName, 'AZ1' as Location, '3093' as Rating from dual union all 
select 'P191R1' as ComputerName, 'AZ1' as Location, '3093' as Rating from dual union all 
select '7CMJ02' as ComputerName, 'AZ3' as Location, '3392' as Rating from dual union all 
select '8W2QS1' as ComputerName, 'AZ4' as Location, '3093' as Rating from dual union all 
select 'K9CHX1' as ComputerName, 'AZ7' as Location, '3192' as Rating from dual union all 
select '3XZNS1' as ComputerName, 'AZ7' as Location, '3093' as Rating from dual union all 
select '79RGX1' as ComputerName, 'AZ9' as Location, '3192' as Rating from dual union all 
select '02BR22' as ComputerName, 'AZ3' as Location, '2593' as Rating from dual 
; 

| ComputerName | Location | Rating | 
|--------------|----------|--------| 
| 4FH6V1  | AZ1  | 3093 | 
| 0GLYQ1  | AZ1  | 3093 | 
| P191R1  | AZ1  | 3093 | 
| 7CMJ02  | AZ3  | 3392 | 
| 8W2QS1  | AZ4  | 3093 | 
| K9CHX1  | AZ7  | 3192 | 
| 3XZNS1  | AZ7  | 3093 | 
| 79RGX1  | AZ9  | 3192 | 
| 02BR22  | AZ3  | 2593 | 

还有更多的记录是这样的表格。例如,我需要找到计算机名称的10%,在有3093.

+1

如果您甚至没有提供足够的信息,您如何期待别人提供帮助?你在用什么SQL?不同的dbms之间的语法不同。 – Eric

回答

2

差饷每个位置如果您使用的是SQL服务器,你可以在你的select语句中使用PERCENT

SELECT TOP 10 PERCENT * FROM tablename WHERE RATING=3093; 
+0

我认为这将只返回所有地点合并的10%,而不是分别为每个地点的10%。所以我需要计算机名称按位置分开,只有10%的计算机名称的分级为3093.我使用的是PERCENT,但无法找出其余的。谢谢。 –

0

如果您正在使用SQL Server,您可以使用apply

select tt.* 
from (select distinct location from t where t.rating = 3093) l apply 
    (select top (10) PERCENT t.* 
     from t 
     where t.location = l.location and t.rating = 3093 
    ) tt 
2

这应该在Oracle工作,虽然样本数据是不是足够大,以获得10%的样本...

create table tablename as 
select '4FH6V1' as ComputerName, 'AZ1' as Location, '3093' as Rating from dual union all 
select '0GLYQ1' as ComputerName, 'AZ1' as Location, '3093' as Rating from dual union all 
select 'P191R1' as ComputerName, 'AZ1' as Location, '3093' as Rating from dual union all 
select '7CMJ02' as ComputerName, 'AZ3' as Location, '3392' as Rating from dual union all 
select '8W2QS1' as ComputerName, 'AZ4' as Location, '3093' as Rating from dual union all 
select 'K9CHX1' as ComputerName, 'AZ7' as Location, '3192' as Rating from dual union all 
select '3XZNS1' as ComputerName, 'AZ7' as Location, '3093' as Rating from dual union all 
select '79RGX1' as ComputerName, 'AZ9' as Location, '3192' as Rating from dual union all 
select '02BR22' as ComputerName, 'AZ3' as Location, '2593' as Rating from dual 
; 

with cte1 as (
select 
    x.ComputerName 
    ,x.Location 
    ,x.Rating 
    ,count(1) over (partition by Location) as location_total 
    ,row_number() over (partition by Location order by ComputerName) as location_position 
    ,row_number() over (partition by Location order by ComputerName)/count(1) over (partition by Location) as location_pct 
from tablename x 
where x.Rating = 3093 
) 
select * 
from cte1 
where location_pct <= 0.1 
+0

不错的一个。仅供参考:从'dual'移除'',它也可以在MSSQL上工作(或者创建一个称为dual的1行虚表)。 '创建表双(x位);插入双选择1'。 – JohnLBevan

+0

这太好了。我需要修改它,因为它由于某种原因没有得到确切的结果。当我手动计数时,我有184台计算机符合x.Rating = 3093条件,但查询只返回9,当它应该是18.我是一个noob,所以我没有完全理解over/partition语句。 –

+0

如果您可以发布更大的数据样本,则可以更容易地找出问题所在。 –

相关问题