首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HQL帮助: Aggregate (count)

HQL帮助: Aggregate (count)
EN

Stack Overflow用户
提问于 2011-03-22 20:05:54
回答 2查看 1.6K关注 0票数 1

给定模型活动,其中包含一个包,其中包含类型为Report (一对多)的模型。我想获得所有活动的列表,其中包含每个活动的报告数量。这两个查询不会带来任何好处,计数器总是1(这是错误的):

代码语言:javascript
复制
select act, (select count(r) from act.Reports r) from Activity act

或者:

代码语言:javascript
复制
select act, count( elements(act.Reports) ) from Activity act group by act.ActivityId, act.Title

有没有可能用HQL编写适当的查询来解决这个简单的任务?

谢谢你给任何小费!sl3dg3

编辑:遵循映射。活动:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class
        name="Core.Models.Config.Activity, Core"
        table="Activity"
    >

        <!-- primary key -->
        <id name="ActivityId" type="Int32" unsaved-value="0" access="property">
            <column name="ActivityId" not-null="true"/>
            <generator class="identity" />
        </id>

        <!-- Properties -->
        <many-to-one name="Title" fetch="join" cascade="all"/>

        <!-- One-To-Many Reports -->
        <bag name="Reports" inverse="true" fetch="join">
            <key column="ReportId" />
            <one-to-many class="Core.Models.Report"/>
        </bag>

    </class>
</hibernate-mapping>

映射报告:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class
        name="Core.Models.Report, Core"
        table="Report"
    >

    <!-- primary key -->
    <id name="ReportId" type="Int32" unsaved-value="0" access="property">
        <column name="ReportId" not-null="true"/>
        <generator class="identity" />
    </id>

    <!-- Properties (shortened - there are more many-to-one and one bag -->
    <property name="Created" />
    <many-to-one name="Activity" column="ActivityId" />

</class>

课堂练习:

代码语言:javascript
复制
public class Activity
{

    public Activity()
    {
        Title = new Translation();
    }

    public virtual int ActivityId { get; set; }

    public virtual Translation Title { get; set; }

    public virtual IList<Report> Reports { get; set; }
}

课堂报告:

代码语言:javascript
复制
public class Report
{

    /// <summary>
    /// HNIBERNATE ONLY
    /// </summary>
    public Report() 
    { }

    /// <summary>
    /// Init Report
    /// </summary>
    public Report(User author)
    {
        // ... Shortened
        Activity = new Activity();
    }

    public virtual Activity Activity { get; set; }

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-03-22 22:26:21

您的第一个HQL查询具有错误的语法。试着这样做:

代码语言:javascript
复制
select act, (select count(*) from act.Reports) from Activity act

您的第二个HQL查询无法工作,因为您将需要GROUP BY子句中的所有列。试着这样做:

代码语言:javascript
复制
select act.ActivityId, act.Title, count( elements(act.Reports) ) 
from Activity act 
group by act.ActivityId, act.Title

编辑:

啊,我想这可能是bug:

代码语言:javascript
复制
<bag name="Reports" inverse="true" fetch="join">
    <key column="ActivityId" /> <-- instead of ReportId
    <one-to-many class="Core.Models.Report"/>
</bag>
票数 1
EN

Stack Overflow用户

发布于 2011-03-23 17:04:20

您希望在SQL中实现的内容如下所示:

代码语言:javascript
复制
select 
  act.*, 
 (select count(*) from Reports rep where rep.id = act.reportId)
from Activity act

使用size()是最简单的,但不幸的是这是不能工作的

代码语言:javascript
复制
select act, size(act.Reports)
from Activity act

根据文档,size在select子句中不可用。有趣的是,it实际上可以在中使用.size,但不能在size()中使用,这实际上应该是等效的:

代码语言:javascript
复制
select act, act.Reports.size
from Activity act

让函数语法(size())正常工作可能是一个值得的特性请求。

官方工作的group by语法很麻烦,因为您需要按所有映射的活动属性进行分组:

代码语言:javascript
复制
select act, count(*)
from Activity act left join act.Reports rep
group by act.id, act.Name, act.Whatever

所以我最终尝试了这个变体,它看起来就是你需要的

代码语言:javascript
复制
select act, (select count(*) from act.Reports)
from Activity act
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5390906

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档