"We are back" « oc.at

Subquery im HQL [java, hibernate]

semteX 24.04.2008 - 10:26 3899 15
Posts

semteX

begehrt die rostschaufel
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14713
Morgen...

ich sitz seit über einer stunde an nem Problem, welches ich früher mittels SQL innerhalb von 10 minuten hatte:

Die Datenbank sieht folgendermaßen aus:

2 Tabellen, Person + Krankheit

Personen haben namen, geburtsdaten, etc
Krankheiten haben nen Namen und ne Dauer.

zwichen Personen und Krankheiten ist ne 1:n, eine person kann also mehrere Krankheiten haben..

Die Aufgabenstellung:

Ich muss herausfinden, wieviel Personen krank waren.
der Teil ist Simpel: SELECT count(*) FROM Person WHERE Person.krankheiten.size > 0;

jetzt wirds happig: Es soll herausgefunden werden, wie LANGE waren diese Personen krank (nicht pro Person sondern für ALLE zusammen!).

der HQL ansatz von mir ist folgender:
Code:
Query query1 = session.createQuery("
SELECT count(*), sum(durs) 
FROM 
          (SELECT sum(k.dauer) as durs 
           FROM Person p 
           LEFT JOIN p.krankheiten k 
           WHERE p.krankheiten.size > 0 
           GROUP BY k.person)
");

nur unterstützt HQL in seinem wahnsinn wieder keine subqueries im FROM part...

wie mach ich das jetzt am besten? Wenn ma das eine query auf 2 aufteilen müssten, wärs auch kein Problem

Thx semteX

Add: versuch 2:

Code:
Query query1 = session.createQuery("
SELECT count(p), sum
      (SELECT sum(k.dauer) FROM p.krankheiten k) 
FROM Person p 
WHERE p.krankheiten.size > 0");

liefert nen fehler beim sum(SELECT)... WAH :(
Bearbeitet von semteX am 28.04.2008, 12:45

prayerslayer

Oar. Mh.
Avatar
Registered: Sep 2004
Location: vorm Sucher
Posts: 4073
vielleicht blick ich auch gar nicht durch, aber was ist mit der query:
Code:
SELECT Person, SUM(dauer)
FROM Person INNER JOIN Krankheit ON (....)
GROUP BY Person

//achso! ich check die aufgabenstellung nicht... wieviele personen waren wie lange krank (10 personen 10 tage, 3 personen 21 tage...) oder einfach nur zusammenzählen, wieviel personen krank waren und wie lange...?

semteX

begehrt die rostschaufel
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14713
du bekommst bei der abfrage dann immer die Person + die Summe seiner krankheitsdauer...

ich will die Anzahl der personen und die summe über die Krankheiten von ALLEN der personen... somit müsst ma da über ein subselect drüberrodeln, was aber Hibernate im FROM teil ned unterstützt... somit wärn ma wieder beim startproblem... SQL wär eh ka problem, HQL is das problem

edit: aufgabenstellung: Wieviel Personen waren krank + wie lange waren diese personen krank. am ende soll rauskommen 330 personen waren insgesammt 499523 tage krank.

prayerslayer

Oar. Mh.
Avatar
Registered: Sep 2004
Location: vorm Sucher
Posts: 4073
ich kann grad leider nur herumraten, weil mein notebook nicht da ist (sql am zettel zähl ich nicht zu meinen stärken), aber vielleicht kriegst ja einen denkanstoß...

was is mit:
Code:
SELECT COUNT(DISTINCT Person), SUM(Dauer)
FROM Person INNER JOIN Krankheit
WHERE --was halt sein muss

:confused:

DKCH

Administrator
...
Registered: Aug 2002
Location: #
Posts: 3301
hint: hql ist kein schreibfehler, sondern eine (sql-ähnliche) abfragesprache, siehe http://www.hibernate.org/hib_docs/v...l/queryhql.html ;)

prayerslayer

Oar. Mh.
Avatar
Registered: Sep 2004
Location: vorm Sucher
Posts: 4073
Zitat von DKCH
hint: hql ist kein schreibfehler, sondern eine (sql-ähnliche) abfragesprache, siehe http://www.hibernate.org/hib_docs/v...l/queryhql.html ;)

gut, hab ich ignoriert, weil's bis auf die punktsyntax wie sql ausgeschaut hat.

my fault, i'm out :)

semteX

begehrt die rostschaufel
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14713
ehrlichgsagt: ich bin ma im moment ned so ganz sicher, wie das funktioniern kann, vor allem das Distinct macht ma kopfweh... du redest hier eh hoffentlich von der HQL oder? weil mit sql hat diese konstruktion nimmer viel ztun (dafür würd das distinct scho an der falschn stelle stehen)

prayerslayer

Oar. Mh.
Avatar
Registered: Sep 2004
Location: vorm Sucher
Posts: 4073
Zitat von semteX
ehrlichgsagt: ich bin ma im moment ned so ganz sicher, wie das funktioniern kann, vor allem das Distinct macht ma kopfweh... du redest hier eh hoffentlich von der HQL oder? weil mit sql hat diese konstruktion nimmer viel ztun (dafür würd das distinct scho an der falschn stelle stehen)

das schnippserl, was oben steht, ist SQL. count(distinct ...) hat bei mir iirc immer funktioniert...

Luzandro

Here to stay
Avatar
Registered: Mar 2006
Location: 2482
Posts: 708
Zitat von semteX
wie mach ich das jetzt am besten? Wenn ma das eine query auf 2 aufteilen müssten, wärs auch kein Problem

Ich hab zwar keine Ahnung von HQL, aber wozu brauchst du überhaupt die Personen, wenn dich nur die Gesamtdauer über alle Krankheiten interessiert? Das klingt für mich eigentl. nach einer simplen Summe über eine Spalte einer einzelnen Tabelle?

semteX

begehrt die rostschaufel
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14713
Zitat von Luzandro
Ich hab zwar keine Ahnung von HQL, aber wozu brauchst du überhaupt die Personen, wenn dich nur die Gesamtdauer über alle Krankheiten interessiert? Das klingt für mich eigentl. nach einer simplen Summe über eine Spalte einer einzelnen Tabelle?
ich demonstrier es am besten:

es interessieren mich nämlich nicht nur die gesamtdauer des ganzen sondern auch wieviel leute waren krank...

Code: PHP
Person
ID       |      Name
1                Hans
2                Franz

Krankheit

ID       |       Name            |     Dauer     |         personId
1                 schnupfen            4                     1
2                 nasenbluten          12                   1
3                 haba haba woot     99                  2
4                 fadheit                 2                    2 

das aufsummiern muss jetzt in 2 schritten passieren, zuerst ein SUM(dauer) as einzeldauer FROM Krankheiten GROUP BY personId

im zweiten schritt will ich aber wissn, wieviel personen waren betroffen UND wie lang waren die alle zusammen krank, also

COUNT (*), SUM(einzeldauer) FROM (SUM(dauer) as einzeldauer FROM Krankheiten GROUP BY personId);

so einfach gehts mit SQL.

wer das ganze jetzt so hintüdelt, dass es mit HQL auch geht, bekommt ein bier. HQL unterstützt keine Subselects im FROM part.

einen "workaround" hab ich jetzt eh scho gefunden: in der datenbank ne view erstellen, welche dieses erste query abbildet, und dann mit hibernate auf diese drauf fahrene...

Luzandro

Here to stay
Avatar
Registered: Mar 2006
Location: 2482
Posts: 708
Dann willst du es also doch in einer einzelnen Query haben

laut dem hql-link oben müsste distinct aber schon funktionieren
Zitat
The distinct and all keywords may be used and have the same semantics as in SQL.
select distinct cat.name from Cat cat

select count(distinct cat.name), count(cat) from Cat cat

also sollte sowohl in sql als auch hql so gehen
Code:
select count(distinct k.personId), sum(k.dauer) from Krankheit k

semteX

begehrt die rostschaufel
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14713
mhm, das könnte so funktioniern... werds am montag in der arbeit probiern, danke!

edit: das vom prayerslayer müsst dann eigentlich auch funktioniern, ich war nur mit dieser syntax ned vertraut...

semteX

begehrt die rostschaufel
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14713
je ein bier an den Luzandro und den prayerslayer... wenn ma uns mal sehen lassts mich ned vergessn, dann geb ich euch eins aus :)

prayerslayer

Oar. Mh.
Avatar
Registered: Sep 2004
Location: vorm Sucher
Posts: 4073
ein bier mit sql verdient... dass ich DAS noch erleben darf :)

semteX

begehrt die rostschaufel
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14713
Zitat von prayerslayer
ein bier mit sql verdient... dass ich DAS noch erleben darf :)
:D
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz