让我们假设一个域类A有许多B类对象。我需要做一个返回
的条件查询此外,查询应该足够灵活,以便为A和B域对象添加条件/限制。 目前我已经达到了这个目标:
A.createCriteria().list {
createAlias('b','b')
projections{
property('id')
property('gender')
property('dateOfBirth')
count('b.id')
property('publicId')
}
}
但问题是它只返回一个对象而且子对象的数量是针对B的所有元素而不仅仅是与A相关的那些元素
答案 0 :(得分:1)
最近我遇到了类似的情况,我需要一个查询,其中一行将以多对多关系存储多个计数
但与您的方案不同,我使用native sql queries来解析查询。
解决方案是使用派生表(我不知道如何使用条件查询来实现它们)。
如果您发现它有用,我会与Grails服务中的实现共享代码:
List<Map> resumeInMonth(final String monthName) {
final session = sessionFactory.currentSession
final String query = """
SELECT
t.id AS id,
e.full_name AS fullName,
t.subject AS issue,
CASE t.status
WHEN 'open' THEN 'open'
WHEN 'pending' THEN 'In progress'
WHEN 'closed' THEN 'closed'
END AS status,
CASE t.scheduled
WHEN TRUE THEN 'scheduled'
WHEN FALSE THEN 'non-scheduled'
END AS scheduled,
ifnull(d.name, '') AS device,
DATE(t.date_created) AS dateCreated,
DATE(t.last_updated) AS lastUpdated,
IFNULL(total_tasks, 0) AS tasks
FROM
tickets t
INNER JOIN
employees e ON t.employee_id = e.id
LEFT JOIN
devices d ON d.id = t.device_id
LEFT JOIN
(SELECT
ticket_id, COUNT(1) AS total_tasks
FROM
tasks
GROUP BY ticket_id) ta ON t.id = ta.ticket_id
WHERE
MONTHNAME(t.date_created) = :monthName
ORDER BY dateCreated DESC"""
final sqlQuery = session.createSQLQuery(query)
final results = sqlQuery.with {
resultTransformer = AliasToEntityMapResultTransformer.INSTANCE
setString('monthName', monthName)
list()
}
results
}
感兴趣的部分是在main select中声明一行,然后在子句中声明派生查询,该查询将结果存储在主select中声明的同名行中
SELECT ...
total_tasks --Add the count column to your select
FROM ticket t
JOIN (SELECT ticked_id, COUNT(1) as total_tasks
FROM tasks
GROUP BY ticked_id) ta ON t.id = ta.ticked_id
...rest of query
我从用户Aaron Dietz向我answer提出的question分享的最后一个例子
我希望它对你有用
答案 1 :(得分:0)
原来我离解决方案还很远,我只需要根据正确的属性进行分组,这是子表中的外键列,在这种情况下是ba,所以现在以下工作< / p>
A.createCriteria().list {
createAlias('b','b')
projections{
property('id')
property('gender')
property('dateOfBirth')
count('b.id')
groupProperty('b.a')
property('publicId')
}
}
答案 2 :(得分:0)
在标准中,您需要按属性进行分组,而不是聚合。
试试以下:
A.createCriteria().list {
createAlias('b','b')
projections{
groupProperty('id','id')
groupProperty('gender','gender')
groupProperty('dateOfBirth','dateOfBirth')
count('b.id','total')
groupProperty('publicId','publicId')
}
}
或者如果您想要一个地图对象返回列表,您可以尝试添加resultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP)
A.createCriteria().list {
resultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP)
createAlias('b','b')
projections{
groupProperty('id','id')
groupProperty('gender','gender')
groupProperty('dateOfBirth','dateOfBirth')
count('b.id','total')
groupProperty('publicId','publicId')
}
}
希望它可以提供帮助