【问题标题】:Ratio of matching rows per group每组匹配行的比率
【发布时间】:2010-10-30 07:23:21
【问题描述】:

我想计算一个组中满足特定条件的项目占该组项目总数的比例。我已经解决了这个问题,但很想知道我的解决方案是否是最优的,因为在我的大型 (10m+) 数据集上查询需要很长时间。

这是我最简单的形式:

create table #tableA 
(
    id int IDENTITY(1,1),
    groupid int,
    flag bit,
    CONSTRAINT [PK_TableA] PRIMARY KEY CLUSTERED 
    (
        [id] ASC
    )
)

insert into #tableA (groupid,flag) values (1,0),(1,0),(1,1),(2,0),(2,1)

select 
    a.groupid ,
    cast(totalCount as float)/count(*) as ratio
from 
    #tableA a 
    join 
    (
        select 
            groupid,
            COUNT(*) totalCount 
        from 
            #tableA 
        where 
            flag=1 
        group by 
            groupid
    ) b on a.groupid=b.groupid 
group by 
    a.groupid,
    b.totalCount

drop table #tableA

有没有更有效的方法来编写这个查询?

【问题讨论】:

    标签: sql tsql group-by


    【解决方案1】:

    假设 flag 是 0 或 1,这应该可以工作:

    select groupid ,
           cast(sum(flag) as float)/count(*) as ratio
    from tableA
    group by groupid
    

    如果flag 可以采用其他值,CASEIF() 应该有助于使SUM 正常工作。

    【讨论】:

    • 我仍在测试,可能需要在关闭前附加到问题
    • @RBarryYoung,你说得对,TSQL(这里不同于 mysql)确实在 SUM 的文档中说“除了位数据类型”,所以它需要一个强制转换(或 CASE 或 IF正如我在答案中提到的更一般的情况)。
    【解决方案2】:

    选择 groupid , AVG(cast(flag as float)) 作为比率 从表 A 按 groupid 分组

    【讨论】:

    • 真的,flag 是来自连接列的 null 或非 null 匹配,因此结合一个 case 语句,为 null 和 1 为非 null(来自 Alex Martelli 的回答),这使得一个优雅的解决方案。谢谢。
    • 我同意,这当然是一个非常优雅的解决方案!对我也很好!谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-19
    • 2018-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多