2017-07-07 2 views
0

alle.Übersetzen Sie MYSQL-Abfrage in HQL mit mehreren JOINS

Ich bin mit Grails 3.3.0.M2 Rahmen mit MySQL als Datenquelle die folgende SQL-Abfrage arbeitet als

SELECT 
    c.name, 
    SUM(CASE 
     WHEN t.status = 'open' THEN 1 
     ELSE 0 
    END) 'open', 
    SUM(CASE 
     WHEN t.status = 'pending' THEN 1 
     ELSE 0 
    END) 'in progress', 
    SUM(CASE 
     WHEN t.status = 'closed' THEN 1 
     ELSE 0 
    END) 'closed' 
FROM 
    tickets t 
     INNER JOIN 
    users u ON t.user_id = u.id 
     INNER JOIN 
    user_coordinations uc ON uc.user_id = u.id 
     INNER JOIN 
    coordinations c ON c.id = uc.coordination_id 
GROUP BY 1 

erwartete ich HQL übersetzt mit impliziten JOIN, aber ich bin immer die falschen Ergebnisse, hier ist die HQL-Abfrage:

SELECT 
    c.name, 
    SUM(CASE 
     WHEN t.status = 'open' THEN 1 
     ELSE 0 
    END), 
    SUM(CASE 
     WHEN t.status = 'pending' THEN 1 
     ELSE 0 
    END), 
    SUM(CASE 
     WHEN t.status = 'closed' THEN 1 
     ELSE 0 
    END) 
FROM 
    Ticket t, User u, UserCoordination uc, Coordination c 
WHERE 
    MONTH(t.dateCreated) = :month 
GROUP BY 1 

um die richtigen Ergebnisse Stack-Überlauf erhalten Anwender helfen Sie mir zu verstehen, dass die Abfrage explizit JOINS verwenden muss, ist hier die Frage: Group by a field that does not belongs to the consulted table

Im Moment habe ich mit der folgenden Abfrage versuchen:

SELECT 
    c.name, 
    SUM(CASE 
     WHEN t.status = 'open' THEN 1 
     ELSE 0 
    END), 
    SUM(CASE 
     WHEN t.status = 'pending' THEN 1 
     ELSE 0 
    END), 
    SUM(CASE 
     WHEN t.status = 'closed' THEN 1 
     ELSE 0 
    END) 
FROM 
    Ticket t 
     INNER JOIN 
    User u 
     INNER JOIN 
    UserCoordination uc 
     INNER JOIN 
    Coordination c 
WHERE 
    MONTH(t.dateCreated) = :month 
GROUP BY 1 

aber ich bin ein com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException mit der verursachten Nachricht bekommen Sie haben einen Fehler in Ihrem SQL-Syntax; Sie in der Bedienungsanleitung zu Ihrem MySQL-Server-Version entspricht, die für die richtige Syntax in der Nähe verwenden ‚innere Verknüpfung user_coordinations usercoordi2_ auf innere Koordinationen verbinden coordinat‘ at line 1

Vielen Dank für Ihre Hilfe und Zeit

Antwort

0
SELECT new map(
    c.name as name, 
(CASE 
     WHEN t.status = 'open' THEN 1 
     ELSE 0 
    END) as open, 
(CASE 
     WHEN t.status = 'pending' THEN 1 
     ELSE 0 
    END) as pending, 
(CASE 
     WHEN t.status = 'closed' THEN 1 
     ELSE 0 
    END) as closed, 
    SUM(open) as openSum, 
    SUM(pending) as pendingSum, 
    SUM(closed) as closedSum 
) 
FROM 
    Ticket t 
     left join t.user u left join u.userCoordination uc left join uc.coordination c 
WHERE 
    MONTH(t.dateCreated) = :month 

// GROUP BY 1

Was Sie viel über mehr vermisst hatte wie das, was Sie benötigen, müssen Sie select new map(i.item as item..., wenn Sie die Grundlagen dieses mit dem vergleichen, was Sie hatten und was ich sehe, kann man versucht zu tun, warum Sie mit Fehlern .

unsicher über Ihre Gruppe, indem es durch etwas gruppiert werden sollte. War nicht sicher durch innere beitreten, wenn Sie nur einen Beitritt gemeint, wenn das der Fall war, lassen Sie alle linken Join seit linken Join versucht, eine Verbindung und erhalten Sie null null hasMany Beziehungen etc.

+0

Vielen Dank für die Beantwortung @ Vahid. 'SELECT NEW ...' ist neu für mich. Ich kann die Vorteile in der Konstruktion der Abfrage sehen. Über die Frage erhalte ich eine _org.hibernate.QueryException_ mit der verursachten Nachricht: _could konnte Eigenschaft nicht auflösen: userCoordination von: ni.edu.ucc.leon.User_ – user615274

+0

Ich denke, das liegt daran, dass es eine Eins-zu-viele-Verbindung zwischen Benutzer und gibt Koordinierung. Wie kann ich das in der Abfrage ausdrücken? Es gibt eine SQL-Fiddle an diesem Ort: http://sqlfiddle.com/#!9/9ed08/1 – user615274

+0

@yuor erste Frage, die Sie haben 'UserCoordination' Ich habe keine Ahnung, was Ihr Domain-Objekt-Mapping dafür ist. Wenn also 'user hasMany = [ucord: UserCoordination] 'das ist, was' links bei u.ucord uc' ist, dann haben Sie das Mapping wie in Ihrem Domain-Objekt deklariert. In Bezug auf deine zweite Frage wird eins zu viele von 'left join' berücksichtigt, wo etwas null ist oder etwas einen Wert hat, der alles erfassen wird. Wenn Sie das Wort 'left' von' join' weglassen, wird 1 Datensatz dafür aufgelistet. Also, wenn links Join und Benutzer1 hat zwei der vielen Datensätze wird es zweimal erscheinen – Vahid