2010-04-07 6 views
0

J'ai cette requête:MySQL utiliser certaines colonnes, sur la base d'autres colonnes

SELECT COUNT(articles.id) AS count 
FROM articles, xml_documents, streams 
WHERE articles.xml_document_id = xml_documents.id 
AND xml_documents.stream_id = streams.id 
AND articles.published_at BETWEEN '2010-01-01' AND '2010-04-01' 
AND streams.brand_id = 7 

qui utilise juste la equajoin par défaut en spécifiant trois tableaux au format csv dans la clause FROM .. Ce que je dois faire est un groupe cela par une valeur trouvée dans les articles.source (XML brut) .. il pourrait se transformer en ceci:

SELECT COUNT(articles.id) AS count, ExtractValue(articles.source, "/article/media_type") AS media_type 
FROM articles, xml_documents, streams 
WHERE articles.xml_document_id = xml_documents.id 
AND xml_documents.stream_id = streams.id 
AND articles.published_at BETWEEN '2010-01-01' AND '2010-04-01' 
AND streams.brand_id = 7 
GROUP BY media_type 

qui fonctionne très bien, le problème est, j'utilise des rails, et l'utilisation de STI pour la table xml_documents . Le articles.source qui est fourni à la méthode ExtractValue sera de plusieurs formats différents .. Donc ce que je dois pouvoir faire est d'utiliser "/ article/media_type" IF xml_documents.type = 'source one' et utilisez "/ article/source" si xml_documents.type = 'source two'

Ceci est juste parce que les deux types de document formatent leur XML différemment, mais je ne veux pas avoir à exécuter plusieurs requêtes pour récupérer cette information ..

ce serait bien si l'on pouvait utiliser un opérateur ternaire, mais je ne pense pas que cela est possible ..

EDIT A ce point, je suis à la recherche à faire une table temporaire, ou simplement en utilisant UNION pour placer plusieurs ensembles de résultats ensemble ..

+0

MySQL prend en charge SQL dynamique via commandes préparées: http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html –

+0

Je ne sais pas comment cela pourrait aider .. – Rabbott

Répondre

3

Qu'en est-il quelque chose comme ceci:

SELECT COUNT(articles.id) AS count, 
     ExtractValue(articles.source, 
      CASE xml_documents.type WHEN 'source one' then '/article/media_type' 
            WHEN 'source two' then '/article/source' 
            ELSE 'error' 
      END), 
FROM ... 

EDIT Essayez ceci:

SELECT COUNT(articles.id) AS count, 
     CASE xml_documents.type WHEN 'source one' THEN ExtractValue(articles.source, '/article/media_type') 
           WHEN 'source two' THEN ExtractValue(articles.source, '/article/source') 
           ELSE NULL 
     END as media_type, 
... 
+0

J'ai été pompé quand j'ai vu ça, ça semble fonctionner, mais MySQL lance "Seules les requêtes XPATH constantes sont supportées", ce qui signifie pour moi que seules les chaînes sont acceptées ici, pas une déclaration de cas ..? Des idées? – Rabbott

+0

C'est décevant. La seule alternative qui me vient à l'esprit est d'écrire une procédure stockée, mais d'après les docs qui ne fonctionneront qu'avec mysql 5.1.20 ou plus récent. –

+0

Bummer, notre serveur exécute le dernier paquet Ubuntu qui est livré avec MySQL Ver 14.12 Distrib 5.0.75, pour debian-linux-gnu (x86_64). Eh bien, je suppose que je vais devoir essayer et juste l'union des multiples ensembles .. – Rabbott

0

J'appuie la affiche précédente:

SELECT 
    COUNT(articles.id) AS count, 
    (CASE xml_documents.type 
     WHEN 'source one' THEN ExtractValue(articles.source, '/article/media_type') 
     WHEN 'source two' then ExtractValue(articles.source, '/article/source') 
     ELSE NULL 
    END) as media_type, 
FROM ... 
+0

Vous devriez upvote sa réponse, plutôt que de créer une autre réponse .. – Rabbott

+0

@Rabbott: J'avais juste posté la requête avant de mettre à jour sa réponse. l'idée était la même de toute façon. – newtover

Questions connexes