20

Is there any way to do the following in HQL:

SELECT 
    case when flag = true then SUM(col1) else SUM(col2)
FROM 
    myTable
Henrik Paul
  • 66,919
  • 31
  • 85
  • 96
lomaxx
  • 113,627
  • 57
  • 144
  • 179
  • yes case is working in HQL now (I am using 3.5.5) http://stackoverflow.com/questions/3778583/problem-with-determining-data-type-of-query-column-in-hibernate – Reddy Sep 24 '10 at 07:55

7 Answers7

13

I guess you can (3.6, 4.3) [inline edit] ...for where-clauses:

"Simple" case, case ... when ... then ... else ... end, and "searched" case, case when ... then ... else ... end

Kariem
  • 4,398
  • 3
  • 44
  • 73
Henrik Paul
  • 66,919
  • 31
  • 85
  • 96
  • 2
    thanks for the reply... unfortunately this is for the where clause not the select statement. – lomaxx Jan 19 '09 at 01:47
7

Apparently the ability to do this was added in 3.0.4, with the limitation that you cannot use sub-selects in the else clause.

Hilton Campbell
  • 6,065
  • 3
  • 47
  • 79
  • 1
    thanks for the post. Unfortunately this is only for Hibernate and not NHibernate... but hopefully with it being in Hibernate it shouldn't be too far away before it's in NHibernate – lomaxx Jan 19 '09 at 21:38
6

See Hibernate-Forum: https://forum.hibernate.org/viewtopic.php?t=942197

Answer from Team (Gavin): case is supported in the where clause, but not in the select clause in HB3.

And seen in JIRA with State "Unresolved".

  • 3
    Which JIRA issue did you look at? I found http://opensource.atlassian.com/projects/hibernate/browse/HHH-467 and it's fixed for 3.0.4. – aberrant80 Jan 19 '10 at 03:18
4

Below you can find a working query (hibernate on postgresql) that uses 2 case statements to replace a boolean value with the corresponding textual representation.

 SELECT 
 CASE ps.open WHEN true THEN 'OPEN' 
      else 'CLOSED' END,  
 CASE ps.full WHEN true THEN 'FULL' 
      else 'FREE' END,  
 ps.availableCapacity 
 FROM ParkingState as ps

Shyam Patel
  • 381
  • 2
  • 13
Ruben
  • 9,056
  • 6
  • 34
  • 44
  • On MSSQL this does not work correctly. I had to use '1' instead of 'true'. : "SELECT CASE ps.open WHEN 1 THEN 'OPEN' else 'CLOSED' END" – Stef Heyenrath May 18 '11 at 09:11
1

I facing the same problem in HQL then I solved the following query is

select CONCAT(event.address1,', ', CASE WHEN event.address2 IS NULL THEN '' ELSE concat(event.address2,', ') END, event.city from EventDetail event where event.startDate>=:startDate and event.endDate<=:endDate;
Faiz Akram
  • 559
  • 4
  • 10
0

We use hibernate HQL query extensively and I think finally there is a hackish way of doing such a thing :

Assuming we originally had a query of

i2.element.id = :someId

Then decided to expand this to be something like this:

((i.element.id = :someId and i2.element.id=:someId) or (i2.element.id = :someId))

But there was an issue where we want it to only lookup for this based on classType so a case statement:

(case when type(i)=Item then 
((i.element.id = :someId and i2.element.id=:someId) or (i2.element.id = :someId))
else
i.element.id = :someId
end)

Above will not work you could make an easy version of above work by doing:

(case when type(i)=Item then 
i2.element.id
else
i.element.id
end)=:elementId

But this does not actually do what we need it to do, we want it to do exact above query, so knowing you can assign a variable at the end of a case statement in there where bit of HQL:

(
                            (
                                (case when 
                                    type(r)=Item then 
                                        i.element.id 
                                    else 
                                        i.element.id end) = :elementId 
                                and 
                                (case when 
                                    type(r)=Item then 
                                        i2.element.id 
                                    else 
                                        i.element.id end) = :elementId
                            )
                            or 
                            (case when 
                                    type(r)=Item then 
                                        i2.element.id 
                                    else 
                                        i.element.id end) = :elementId 
                            )

I have managed to make the query now work based on case statement, sure it is a lot more long winded but actually does the same as the first instance

V H
  • 8,382
  • 2
  • 28
  • 48
-2

This is an example using a string comparison in the condition:

SELECT CASE f.type WHEN 'REMOVE'
                   THEN f.previousLocation 
                   ELSE f.currentLocation 
       END 
FROM FileOperation f
tibi
  • 657
  • 1
  • 10
  • 22