Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Erreur de requête SQL dans les clauses Group By et Order By

Lorsque vous utilisez GROUP BY vous aurez normalement des fonctions d'agrégation , le SQL que vous avez fourni ne contient en fait aucune fonction d'agrégation, il n'est donc pas nécessaire de le regrouper.

SELECT  
    m.Message_Id 
    , m.Chat_Relation_Id AS relation_id 
    , m.SenderId AS datetime 
    , m.Text_Message 
    , m.Subject 
    , m.DateTime
FROM  
    [AppResource].[dbo].[ChatMessage] AS m  
    INNER JOIN [AppResource].[dbo].[chatRelation] AS r 
    ON r.Chat_Relation_Id = m.Chat_Relation_Id 
WHERE  
    r.User1Id=1 
GROUP BY 
    m.Chat_Relation_Id 
ORDER BY  
    m.DateTime desc

L'erreur est générée car toutes les colonnes non agrégées doivent être définies dans le GROUP BY clause car elle définit la manière dont les autres colonnes (agrégatives) sont calculées. Dans votre cas et compte tenu du problème décrit, je suppose qu'il suffit de supprimer le GROUP BY résoudra votre problème.

SELECT  
    m.Message_Id 
    , m.Chat_Relation_Id AS relation_id 
    , m.SenderId AS datetime 
    , m.Text_Message 
    , m.Subject 
    , m.DateTime
FROM  
    [AppResource].[dbo].[ChatMessage] AS m  
    INNER JOIN [AppResource].[dbo].[chatRelation] AS r 
    ON r.Chat_Relation_Id = m.Chat_Relation_Id 
WHERE  
    r.User1Id = 1 
ORDER BY  
    m.DateTime DESC

Modifier après un commentaire concernant les entrées en double :

La requête suivante obtiendra l'entrée la plus récente pour chaque Chat_Relation_Id

SELECT  
    m.Chat_Relation_Id AS relation_id 
    , MAX(m.DateTime) AS maxDateTime
FROM  
    [AppResource].[dbo].[ChatMessage] AS m  
    INNER JOIN [AppResource].[dbo].[chatRelation] AS r 
    ON r.Chat_Relation_Id = m.Chat_Relation_Id 
WHERE  
    r.User1Id = 1 
GROUP BY 
    m.Chat_Relation_Id 

C'est loin d'être idéal, mais pourrait être utilisé comme sous-requête pour sélectionner le texte pertinent comme suit :

SELECT  
    m.Message_Id 
    , m.Chat_Relation_Id AS relation_id 
    , m.SenderId AS datetime 
    , m.Text_Message 
    , m.Subject 
    , m.DateTime
FROM  
    (SELECT  
        subqueryMessage.Chat_Relation_Id AS relation_id 
        , MAX(subqueryMessage.DateTime) AS maxDateTime
    FROM  
        [AppResource].[dbo].[ChatMessage] AS subqueryMessage  
        INNER JOIN [AppResource].[dbo].[chatRelation] AS subQueryRelation 
        ON subQueryRelation.Chat_Relation_Id = subqueryMessage.Chat_Relation_Id 
    WHERE  
        subQueryRelation.User1Id = 1 
    GROUP BY 
        subqueryMessage.Chat_Relation_Id 
    ) AS mySubQuery
    INNER JOIN [AppResource].[dbo].[ChatMessage] AS m  
    ON  m.Chat_Relation_Id = mySubQuery.relation_id
        AND m.DateTime = mySubQuery.maxDateTime
ORDER BY  
    m.DateTime DESC

Je n'aime pas utiliser des sous-requêtes comme celle-ci, mais je suis un développeur et non un administrateur de base de données, et ce qui précède est limité de sorte que s'il existe des éléments avec le même Chat_Relation_Id et DateTime alors les doublons se produiront toujours. Il existe probablement une manière astucieuse de le faire en utilisant un HAVING Clause mais j'espère que si cela ne vous donne pas quelque chose sur quoi travailler, cela aidera quelqu'un d'autre à résoudre votre problème.