Usando una declaración CASE en HQL select
-
19-08-2019 - |
Pregunta
¿Hay alguna forma de hacer lo siguiente en HQL:
SELECT
case when flag = true then SUM(col1) else SUM(col2)
FROM
myTable
Otros consejos
Aparentemente, la capacidad de hacer esto fue agregado en 3.0.4 , con la limitación de que no puede usar sub-selecciones en la cláusula else.
Ver Hibernate-Forum: https://forum.hibernate.org/viewtopic.php ? t = 942197
Respuesta del equipo (Gavin): case se admite en la cláusula where, pero no en la cláusula select en HB3.
Y visto en JIRA con Estado "No resuelto".
A continuación puede encontrar una consulta de trabajo (hibernar en postgresql) que utiliza 2 declaraciones de caso para reemplazar un valor booleano con la representación textual correspondiente.
SELECCIONE CASO ps.abrir CUANDO sea cierto ENTONCES 'ABIERTO' más 'CERRADO' FIN, CASO ps.full CUANDO es cierto LUEGO 'COMPLETO' más FIN 'GRATIS', ps.disponibleCapacidad DESDE ParkingState como ps
Usamos la consulta HQL de Hibernate ampliamente y creo que finalmente hay una forma hack de hacer tal cosa:
Suponiendo que originalmente teníamos una consulta de
i2.element.id =: someId
Luego decidió expandir esto para que sea algo así:
((i.element.id =: someId y i2.element.id =: someId) o (i2.element.id =: someId))
Pero hubo un problema en el que queremos que solo busque esto basado en classType, por lo que una declaración de caso:
(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)
Arriba no funcionará, podría hacer una versión fácil del trabajo anterior haciendo:
(case when type(i)=Item then
i2.element.id
else
i.element.id
end)=:elementId
Pero en realidad esto no hace lo que necesitamos que hagamos, queremos que haga exactamente la consulta anterior, así que sabiendo que puede asignar una variable al final de una declaración de caso allí donde un poco de 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
)
He logrado hacer que la consulta ahora funcione en función de la declaración del caso, seguro que es mucho más larga pero en realidad hace lo mismo que la primera instancia
Estoy enfrentando el mismo problema en HQL y luego resolví que la siguiente consulta es
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;
Este es un ejemplo usando una comparación de cadenas en la condición:
SELECT CASE f.type WHEN 'REMOVE'
THEN f.previousLocation
ELSE f.currentLocation
END
FROM FileOperation f