Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Errore di query SQL in Raggruppa per e Ordina per clausola

Quando utilizzi GROUP BY normalmente avrai funzioni aggregate , l'SQL che hai fornito non contiene alcuna funzione aggregata, quindi non è necessario che venga raggruppato.

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

Viene generato l'errore perché tutte le colonne non aggregate devono essere definite in GROUP BY clausola in quanto definisce come vengono calcolate le altre colonne (aggregate). Nel tuo caso e dato il problema descritto, suppongo di aver semplicemente rimosso il GROUP BY risolverà il tuo problema.

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

Modifica dopo il commento relativo alle voci duplicate:

La seguente query otterrà la voce più recente per ogni 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 

Questo è tutt'altro che ideale, ma potrebbe essere utilizzato come sottointerrogazione per selezionare il testo pertinente come segue:

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

Non mi piace usare sottoquery come questa, ma sono uno sviluppatore non un DBA, e quanto sopra è limitato in modo tale che se ci sono elementi con Chat_Relation_Id identico e DateTime quindi si verificheranno ancora duplicati. Probabilmente c'è un modo intelligente per farlo usando un HAVING Clausola ma si spera che se questo non ti dà qualcosa su cui lavorare, aiuterà qualcun altro a risolvere il tuo problema.