Domanda

Esiste un modo per eseguire le seguenti operazioni in HQL:

SELECT 
    case when flag = true then SUM(col1) else SUM(col2)
FROM 
    myTable
È stato utile?

Soluzione

Credo che tu possa ( 3.6 , 4.3 ) [modifica in linea] ... per clausole where:

  

" Simple " case, case ... when ... then ... else ... end e " cercato " case, case when ... then ... else ... end

Altri suggerimenti

Apparentemente la possibilità di farlo era aggiunto in 3.0.4 , con la limitazione che non è possibile utilizzare i sottoselezioni nella clausola else.

Vedi il forum di Hibernate: https://forum.hibernate.org/viewtopic.php ? t = 942197

Risposta del team (Gavin): case è supportato nella clausola where, ma non nella clausola select in HB3.

E visto in JIRA con lo stato "Non risolto".

Di seguito è possibile trovare una query funzionante (ibernazione su postgresql) che utilizza 2 istruzioni case per sostituire un valore booleano con la rappresentazione testuale corrispondente.

  

SELEZIONA CASO ps.open QUANDO vero ALLORA   'APERTO' altrimenti 'CHIUSO' FINE, CASO   ps.full QUANDO è vero ALLORA 'PIENO' altro   FINE 'GRATUITA', ps.availableCapacity   DA ParkingState come ps

Usiamo ampiamente la query HQL ibernata e penso che finalmente ci sia un modo hacker di fare una cosa del genere:

Supponendo che inizialmente avevamo una query di

i2.element.id =: someId

Quindi ha deciso di espandere questo per essere qualcosa del genere:

((i.element.id =: someId e i2.element.id =: someId) o (i2.element.id =: someId))

Ma c'era un problema in cui desideravamo che cercasse questo solo in base a classType, quindi un'istruzione case:

(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)

Sopra non funzionerà, puoi fare una versione facile di sopra facendo:

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

Ma questo in realtà non fa ciò di cui abbiamo bisogno, vogliamo che faccia esattamente la query sopra, quindi sapendo che puoi assegnare una variabile alla fine di un'istruzione case là dove bit di 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 
                            )

Sono riuscito a far funzionare ora la query in base all'istruzione case, certo che è molto più lungo ma in realtà fa lo stesso della prima istanza

Ho riscontrato lo stesso problema in HQL, quindi ho risolto la seguente query

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;

Questo è un esempio che utilizza un confronto di stringhe nella condizione:

SELECT CASE f.type WHEN 'REMOVE'
                   THEN f.previousLocation 
                   ELSE f.currentLocation 
       END 
FROM FileOperation f
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top