2011-03-22 89 views
1

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

select act, (select count(r) from act.Reports r) from Activity act 

或者:

select act, count(elements(act.Reports)) from Activity act group by act.ActivityId, act.Title 

是否有可能写HQL合适的查询来解决这个简单的任务?

Thx for any tipps! sl3dg3

编辑: 映射后。活动:

<?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> 

映射报告:

<?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> 

类的活动:

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; } 
} 

类报告:

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; } 

} 

回答

1

您的第一个HQL查询语法错误。试试这个:

select act, (select count(*) from act.Reports) from Activity act 

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

select act.ActivityId, act.Title, count(elements(act.Reports)) 
from Activity act 
group by act.ActivityId, act.Title 

编辑:

啊,我想这可能是错误:

<bag name="Reports" inverse="true" fetch="join"> 
    <key column="ActivityId" /> <-- instead of ReportId 
    <one-to-many class="Core.Models.Report"/> 
</bag> 
+0

至于第一个查询:不幸的是,我仍然得到每个活动一(并且只有一个)报告作为计数。至于第二个查询,这正是我上面写的 - 我的也是正确的,但没有很好格式化;-) – sl3dg3 2011-03-22 16:39:33

+0

@ sl3dg3对不起,我没有正确测试这些。我只是在测试环境中测试了这些查询,并且它们运行良好。你可以发布映射和类定义吗? – 2011-03-22 22:42:38

+0

@Florian我在原帖中添加了映射... – sl3dg3 2011-03-23 08:35:26

2

你想实现什么是SQL是这样的:

select 
    act.*, 
(select count(*) from Reports rep where rep.id = act.reportId) 
from Activity act 

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

select act, size(act.Reports) 
from Activity act 

根据该文档,size不是SELECT子句中使用。有趣的是,它的实际工作.size,但不能与size(),这实际上应该是等价的:

select act, act.Reports.size 
from Activity act 

这可能是值得的功能要求也使函数语法(size())工作。

的正式工作组由语法很麻烦,因为你需要组由所有映射的活动性质:

select act, count(*) 
from Activity act left join act.Reports rep 
group by act.id, act.Name, act.Whatever 

于是,我终于尝试这个变体,它似乎是正是你需要

select act, (select count(*) from act.Reports) 
from Activity act 
+0

测试这一点,但生成的SQL('选择activity0_.ActivityId如col_0_0_, \t计数(reports1_.ReportId)作为col_1_0_,activity0_.ActivityId如ActivityId12_,activity0_.Title如Title12_ 从活动activity0_,报告reports1_ 其中activity0_。 ActivityId = reports1_.ReportId')失败说:'Column'Activity.ActivityId'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。“ – sl3dg3 2011-03-23 09:30:19

+0

我更新了我的答案。 – 2011-03-23 10:11:53

+0

Thx - 事实证明我有一个映射 - 错误(见上文)。到目前为止,你已经提出了相同的解决方案:-) – sl3dg3 2011-03-23 10:39:38