How to rewrite HQL query with `distinct(year())` as Criteria - grails

I ran below HQL Query, I got [2015,2014]
select DISTINCT(YEAR(SP.deliveryDate)) from SupplyPlan as SP where SP.samplePlan=2
Above query I need in criteria, I have tried like below but it is not working. Any suggestions?
def supplyPlanCriteria=SupplyPlan.createCriteria()
def list=supplyPlanCriteria.list {
projections {
property("YEAR(deliveryDate)")
}
eq("samplePlan",samplePlan)
}

Related

Grails distinct projection get the result count of distinct items

I am using grails-2.5.6 version. I am using spring-security-core plugin. I have a criteria query on UserRole table. Where I want to find all distinct users by a role. It is working properly.
But the problem is the pagination effect. When I am counting on the list it is counting on UserRole list object. But I need the count on distinct projection items. Here is my attempt below:
def list(Integer max) {
def userInstanceList = UserRole.createCriteria().list(params) {
createAlias('user', 'au')
createAlias('role', 'ar')
projections {
distinct("user")
}
if (params.roleId) {
eq('ar.id', params.getLong("roleId"))
}
}
def totalCount = userInstanceList.totalCount
[userInstanceList: userInstanceList, totalCount: totalCount]
}
Here, totalCount is the number of UserRole list. But I want the distinct projection count.
I would tackle this slightly differently, you want to analyse the users, not the userroles.
So I'd do something like:
List<User> usersWithRole = UserRole.createCriteria().list(params) {
role {
eq('id', params.getLong("roleId"))
}
}*.user
int count = usersWithRole.size()
Unless of course there's hundreds or thousands of users, in which case I wouldn't want to load all of them each time and would revert to SQL.
Is this a custom version of spring security you're using? I've never seen Roles with a 'long' based ID, usually, the key is a String representing the Authority name.
Usually the DBAs see the use of distinct keyword as a code-smell.
In your case I would rather use the User as the main domain object to run the query against and a group by clause:
long id = params.getLong "roleId"
def list = User.createCriteria().list( params ) {
projections{
groupProperty 'userRole.role.id'
}
if( id )
userRole{
role{
eq 'id', id
}
}
}

How to get a list of distinct records with projections in grails?

Is there a way that I can get a list of distinct Order objects (based on customerName) with projections (selected fields only)?
Assuming only the id would be different, I want to fetch orders having unique customerName. Is it possible using projections or any other way?
My code is:
def criteria = Order.createCriteria()
def orders = criteria.list() {
and {
eq("showAddress", true)
like("customerName", "%abcdPqrs%")
}
projections {
distinct("customerName")
property("deliveryAddress")
property("billingAddress")
property("")
}
}
return orders
The above code fetches duplicate (customerName) records from Order, how can I fix this?
If you will see the SQL query generated by GORM, you will find that the distinct will apply on a complete row instead of the customerName. You can enable the logs by putting
logSql = true
in datasource.groovy.
You can try this
def criteria = Order.createCriteria()
def orders = criteria.list() {
and {
eq("showAddress", true)
like("customerName", "%abcdPqrs%")
}
projections {
groupProperty("customerName")
property("deliveryAddress")
property("billingAddress")
property("")
}
}

Having clause in GORM

I have a domain class named Keyword and I need to run a query to get all the duplicate keywords in the system, base on some criteria.
The query in MySQL is somethine like this:
select keywordid, md5, match_type, count(md5)
from keyword
where site_id = 'MLU'
and customer_id = 1075613440
group by md5
having count(md5) > 1;
Now I need to "translate" this query to Grails but the requirement from my boss is to aviod HQL.
Is it possible to do it?
For now all I have is this:
def dupKws = criteria.list {
eq('siteId', siteId)
eq('customerId', account.customerId)
projections {
groupProperty('md5')
groupProperty('matchType')
rowCount()
}
}
You can run this query in grails with:
import groovy.sql.Sql
def query = """ select keywordid, md5, match_type, count(md5)\
from keyword\
where site_id = 'MLU'\
and customer_id = 1075613440\
group by md5\
having count(md5) > 1 """
Sql sql = new Sql(datasource)
sql.execute(query)

findAll() HQL not returning paginated list in grails

I am working on a grails application, in this I have to apply filter box on list.gsp. When I am filtering using following query(in my service) I am getting paginated list :
def clientCriteria = TripOrder.createCriteria()
def searchResults = clientCriteria.list(max: params.max, offset: params.offset, sort: params.sort, order: params.order){
ilike("origin", "${searchFor}%")
}
println searchResults.getTotalCount()
[searchResults: searchResults, searchResultSize: searchResults.getTotalCount()]
But my problem is that when I am using findAll, I am not able to get paginated list, query as follows :
def searchResults = TripOrder.findAll("from TripOrder as t where t.status.status=:status", [status: searchFor], [max: maximum, sort: params.sort, order: params.order])
println searchResults.size()
[searchResults: searchResults, searchResultSize: searchResults.size()]
Note : Because of some reasons I have to use findAll() HQL instead criteria queries.
Above result provide only number of list equal to max instead of provide paginated list.
Please provide me solution for getting paginated list using findAll().
Thanks.
Based on your comment, you can do like this where you get a PagedResultList
def results = TripOrder.createCriteria.list(params) {
customer {
ilike 'firstName', "%$searchFor%"
}
}
assert results.size() != results.totalCount
It basically fires another query for the totalCount, if you want to stick to findAll or something like findAll instead of criteria then you can imbibe a better alternative by using a DetachedCriteria/where query which lazily executes the query on demand. Again, you won't be able to get the total count in first query. You have to fire another for the same.
def query = TripOrder.where {
customer.firstName =~ searchFor
}
//Query executed only when list() is called
def results = query.list( params )
//Only executed when count() is called
def totalCount = query.count()
findAll isn't designed to return a paginated list. It returns an array. This is clearly stated in the documentation.

Grails createCriteria group by

How can I get something like this MYSQL query with createCriteria in grails?
SELECT *
FROM engine4_user_fields_values
WHERE field_id = 31 OR field_id = 24
GROUP BY item_id;
It works fine if I use something like this:
def items = items_c.list{
'in'('fieldId',field_ids)
projections{
groupProperty("itemId")
}
}
But I need to define order, max and sort field like this:
def items = items_c.list(max:5, sort:"itemId", order:"desc"){
'in'('fieldId',field_ids)
projections{
groupProperty("itemId")
}
}
But this gets me different rows with the same 'item_id'
What can I do?
How about listDistinct{} ?
http://grails.org/doc/latest/guide/5.%20Object%20Relational%20Mapping%20(GORM).html#5.4.2 Criteria
Use the projection agains the first result,
lists= items.createCriteria().list(){
projections {
order ("ItemId")
}
}
or executeQuery("your Query Here"); with distnict

Resources