none
Erreur de sous-requête RRS feed

  • Question

  • Bonjour,

    Je tente de faire la requête suivante:


    SELECT  T.ID AS 'key', T.SentenceID AS 'rowIndex', T.SentenceCategoryID AS 'type',

    'English' = MAX(
                          CASE WHEN (
                                            TR.LanguageID = 1 AND TR.RevisionID IN
                                                      (SELECT MAX(RevisionID) FROM Translate AS TR1  -- get max RevisionID for this word
                                                       WHERE TR.SentenceID = TR1.SentenceID AND TR.LanguageID = TR1.LanguageID))
                        THEN TR.TranslateString  ELSE NULL END)

    /* plus de 50 langues */

     
    FROM TranslateSentence AS T
    LEFT OUTER JOIN Translate TR ON T.SentenceID = TR.SentenceID 

    GROUP BY T.ID, T.SentenceID, T.SentenceCategoryID
    ORDER BY RS1ID


    et j'obtient l'erreur suivante: Cannot perform an aggregate function on an expression containing an aggregate or a subquery

    Je comprend donc que je ne peux pas effectuer de sous requête lors d'un group by
    Je peux facilement contourner ce problème avec une jointure..  mais, si l'on considère que j'ai plus de 50 langues contenant plus de 10000 mots..  j'ai le temps d'aller faire mon lavage avant que la requête se termine.

    Quelqu'un connaitrait une autre méthode plus efficace afin d'effectuer la requete?

    Merci
    mercredi 30 décembre 2009 22:49

Réponses

  • Bon, en y regardant de plus près, et en partant du fait que tu veux pour chacun des triplés (Id,SentenceId,SentenceCategoryId) obtenir toutes les traductions dans toutes les langues :

    Voilà le type de requête que je ferai si je voulais le faire en one-shot, en imaginant que l'anglais est la langue 1, et l'allemand la langue 2 :

    select T.ID AS 'key', T.SentenceID AS 'rowIndex', T.SentenceCategoryID AS 'type',
    (SELECT TR.TranslateString FROM Translate TR WHERE T.SentenceID = TR.SentenceID AND TR.LanguageID = 1 AND TR.RevisionId =
    (SELECT MAX(TR2.RevisionId) FROM Translate TR2 WHERE TR2.LanguageId = TR.LanguageId AND TR2.SentenceID = TR.SentenceID)) AS 'English',
    (SELECT TR.TranslateString FROM Translate TR WHERE T.SentenceID = TR.SentenceID AND TR.LanguageID = 2 AND TR.RevisionId =
    (SELECT MAX(TR2.RevisionId) FROM Translate TR2 WHERE TR2.LanguageId = TR.LanguageId AND TR2.SentenceID = TR.SentenceID)) AS 'German'

    /* etc ... pour les autres langues */

    FROM TranslateSentence T

    Sinon, pourquoi ne pas le faire en 2 phases avec une table temporaire, c'est peut-être plus rapide ?
    Mais ça veut dire que tu as droit à faire une proc stock ...

    Si tu veux que je regarde de plus près, dis-le moi.

    Cordialement,

    Thomas


    Thomas Aimonetti - C# - Sharplog Engineering
    lundi 4 janvier 2010 17:17
  • Effectivement, j'ai résolu mon problème avec une table temporaire.. Je crois que ca prend un peu plus de temps à l'exécution.. environ 10 - 15 secondes de plus..  mais ca reste très acceptable pour l'application que je développe.

    Merci
    • Marqué comme réponse Alex Petrescu mardi 5 janvier 2010 09:34
    lundi 4 janvier 2010 19:34

Toutes les réponses

  • Bonjour,

    Je ne comprends pas vraiment ta requête :

    SELECT  T.ID AS 'key', T.SentenceID AS 'rowIndex', T.SentenceCategoryID AS 'type',

    'English' = MAX(
                          CASE WHEN (
                                            TR.LanguageID = 1 AND TR.RevisionID IN
                                                      (SELECT MAX(RevisionID) FROM Translate AS TR1  -- get max RevisionID for this word
                                                       WHERE TR.SentenceID = TR1.SentenceID AND TR.LanguageID = TR1.LanguageID))
                        THEN TR.TranslateString  ELSE NULL END)

    /* plus de 50 langues */
     
    FROM TranslateSentence AS T
    LEFT OUTER JOIN Translate TR ON T.SentenceID = TR.SentenceID 

    GROUP BY T.ID, T.SentenceID, T.SentenceCategoryID
    ORDER BY RS1ID


    C'est quoi ce MAX que j'ai mis en gras ?
    De ton CASE WHEN dans ta sous-requête, il en sort soit la derniere revision de la correction, donc une STRING, soit NULL.

    Peux-tu expliquer le résultat que tu veux obtenir ?

    Cordialement,

    Thomas
    Thomas Aimonetti - C# - Sharplog Engineering
    lundi 4 janvier 2010 16:31
  • Bon, en y regardant de plus près, et en partant du fait que tu veux pour chacun des triplés (Id,SentenceId,SentenceCategoryId) obtenir toutes les traductions dans toutes les langues :

    Voilà le type de requête que je ferai si je voulais le faire en one-shot, en imaginant que l'anglais est la langue 1, et l'allemand la langue 2 :

    select T.ID AS 'key', T.SentenceID AS 'rowIndex', T.SentenceCategoryID AS 'type',
    (SELECT TR.TranslateString FROM Translate TR WHERE T.SentenceID = TR.SentenceID AND TR.LanguageID = 1 AND TR.RevisionId =
    (SELECT MAX(TR2.RevisionId) FROM Translate TR2 WHERE TR2.LanguageId = TR.LanguageId AND TR2.SentenceID = TR.SentenceID)) AS 'English',
    (SELECT TR.TranslateString FROM Translate TR WHERE T.SentenceID = TR.SentenceID AND TR.LanguageID = 2 AND TR.RevisionId =
    (SELECT MAX(TR2.RevisionId) FROM Translate TR2 WHERE TR2.LanguageId = TR.LanguageId AND TR2.SentenceID = TR.SentenceID)) AS 'German'

    /* etc ... pour les autres langues */

    FROM TranslateSentence T

    Sinon, pourquoi ne pas le faire en 2 phases avec une table temporaire, c'est peut-être plus rapide ?
    Mais ça veut dire que tu as droit à faire une proc stock ...

    Si tu veux que je regarde de plus près, dis-le moi.

    Cordialement,

    Thomas


    Thomas Aimonetti - C# - Sharplog Engineering
    lundi 4 janvier 2010 17:17
  • Effectivement, j'ai résolu mon problème avec une table temporaire.. Je crois que ca prend un peu plus de temps à l'exécution.. environ 10 - 15 secondes de plus..  mais ca reste très acceptable pour l'application que je développe.

    Merci
    • Marqué comme réponse Alex Petrescu mardi 5 janvier 2010 09:34
    lundi 4 janvier 2010 19:34