views:

82

answers:

2

I have this query:

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

Which just uses the default equajoin by specifying three tables in csv format in the FROM clause.. What I need to do is group this by a value found within articles.source (raw xml).. so it could turn into this:

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

which works fine, the problem is, I'm using rails, and using STI for the xml_documents table. The articles.source that is provided to the ExtractValue method will be of a couple different formats.. So what I need to be able to do is use "/article/media_type" IF xml_documents.type = 'source one' and use "/article/source" if xml_documents.type = 'source two'

This is just because the two document types format their XML differently, but I don't want to have to run multiple queries to retrieve this information..

It would be nice if one could use a ternary operator, but i don't think this is possible..

EDIT At this Point I am looking at making a temp table, or simply using UNION to place multiple result sets together..

+2  A: 
Jason Day
I was pumped when I saw this, seems like it should work, but MySQL throws "Only constant XPATH queries are supported", which to me, means that only strings are accepted here, not a case statement..? Ideas?
Rabbott
That's disappointing. The only alternative that occurs to me is to write a stored procedure, but according to the docs that will only work with mysql 5.1.20 or newer.
Jason Day
Bummer, our server is running the latest Ubuntu package which is packed with MySQL Ver 14.12 Distrib 5.0.75, for debian-linux-gnu (x86_64). Well I guess I will have to try and just union the multiple sets..
Rabbott
Could this be done using a left join of some sort? Joining the same table multiple times with different criteria...
Rabbott
perfect! Thanks for staying with me
Rabbott
Great! It was a bit of a face-palm moment, not sure why I didn't think of it sooner.
Jason Day
A: 

I would support the previous poster:

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 ...
newtover
You should upvote his response, rather than creating another answer..
Rabbott
@Rabbott: I just had posted the query before he updated his answer. the idea was the same anyway.
newtover