Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

MySQL question

by Kozz (Friar)
on Mar 28, 2002 at 21:35 UTC ( #155114=perlquestion: print w/ replies, xml ) Need Help??
Kozz has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks: Please forgive me for asking this question here, but in my estimation it seems that there are MANY monks here with extensive database experience.

I'll provide a minimal test-case for you to chew on. Given a MySQL table with the following content:

id | title | doc_num | version ---+-------+---------+-------- 1 | bar | 1234 | 1 2 | foo | 1234 | 2 3 | baz | 5678 | 1
I want to do something like
SELECT title, doc_num, MAX(version) AS version ORDER BY title; which produces this: title | doc_num | version -------+---------+-------- bar | 1234 | 2 baz | 5678 | 1
The problem is that the ORDER BY clause ends up sorting by the title of the older version, "bar" rather than the title for the latest version, "foo". Of course, what I REALLY want is the title from the document with the greatest version. Is there a way to do this in a single query, without using sub-selects or other such tedious things?

Or is my database hopelessly structured incorrectly?

My humblest thanks. If this question is hopelessly inappropriate, just "--" me into oblivion and please recommend a penance for my sins. ;)

Comment on MySQL question
Select or Download Code
Re: MySQL question
by shadox (Priest) on Mar 28, 2002 at 21:51 UTC
    If i understand you well ( i am half asleep ), what you want is a list of titles with the greatest version.
    Something like this
    +-------+---------+---------+ | title | doc_num | version | +-------+---------+---------+ | bar | 1234 | 9 | | foo | 1234 | 7 | | other | 2121 | 7 | +-------+---------+---------+
    Well if it is right, all what you need is to change your ORDER BY, for a GROUP by.
    SELECT title, doc_num, MAX(version) AS version from test GROUP BY titl +e; # For this example "test" is the table name


    Failure is not an option - it is a privilege reserved for
    those who do not try hard enough.

Re: MySQL question
by Jazz (Curate) on Mar 28, 2002 at 21:52 UTC

    To get the highest number, you can just order by version in descending order:

    SELECT title, doc_num ORDER by version DESC

    Or is there a particular reason you want to use MAX?

    Also, if you just want the one with the latest version, then you can use the LIMIT clause to get only one result:

    SELECT title, doc_num ORDER by version DESC LIMIT 1
Re: MySQL question
by Juerd (Abbot) on Mar 28, 2002 at 22:01 UTC

    Please forgive me for asking this question here, but in my estimation it seems that there are MANY monks here with extensive database experience.

    Your estimation is correct. A lot of us know a big deal about cars, too. But this site isn't the appropriate place for that. Sorry, I --'ed your post.

    I'd feel really bad if I only complained without trying to answer your question, so here goes:
    Hmm, you didn't really state what data you would expect very clearly.

    Maybe it's one of these (untested): SELECT title, doc_num, version FROM foo ORDER BY version DESC LIMIT 1 SELECT title, doc_num, MAX(version) AS maxver FROM foo GROUP BY title +ORDER BY maxver DESC

    U28geW91IGNhbiBhbGwgcm90MTMgY
    W5kIHBhY2soKS4gQnV0IGRvIHlvdS
    ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
    geW91IHNlZSBpdD8gIC0tIEp1ZXJk
    

      In the spirit of sportsman-like conduct, I ++'ed your post. Mostly the reason I venture to ask this question here is because it's a reasonable forum with intelligent persons of moderate tempers. ;) I don't get along with usenet very well, some IRC channels seem to smack of elitism, and don't know of any other online forums that would be better suited to answer my question.

      Anyhow, to answer your question, I was hoping to get one row per distinct doc_num whose version was the max() of all versions for that doc_num, and whose title corresponded to the record with the max version:

      title | doc_num | version -------+---------+-------- foo | 1234 | 2 baz | 5678 | 1
      Compare my chart above to the "original" and you may see what I mean.

      Anyhow, my apologies for tempting fate in this manner. If I've overstepped my bounds by replying to your post, I once again apologize. But if you find the breath to chastize me once more, I also welcome links to any Database-related forums. ;)

        Ahh. Then again, with a real database with subselects, that'd be:
        SELECT title, doc_num, version FROM atable WHERE (doc_num, version) IN ( SELECT doc_num, MAX(version) FROM atable GROUP BY doc_num );
        Again, this won't work in puny MySQL. PostgreSQL or better, baby!

        -- Randal L. Schwartz, Perl hacker


        Reason: (Jazz) Delete - by author (me) request

        For more information on this node visit: this

•Re: MySQL question
by merlyn (Sage) on Mar 28, 2002 at 22:21 UTC
    Of course, what I REALLY want is the title from the document with the greatest version.
    Well, in a real database, you'd do that as:
    SELECT title FROM atable WHERE version = (SELECT MAX(version) FROM ata +ble)
    But since MySQL doesn't have subselects... {heh heh}.

    Time to upgrade to PostgreSQL. Better, faster, cheaper, and more powerful. And able to do typical database things as the big boys do them.

    -- Randal L. Schwartz, Perl hacker


    update: after the later clarification, see my other post "•Re: Re: Re: MySQL question" for a more accurate solution...
Re: MySQL question
by rbc (Curate) on Mar 28, 2002 at 22:43 UTC
    You could try this ...
    1 select D.title, D.doc_num, D.version from junk D, 2 ( 3 SELECT 4 A.doc_num doc_num 5 , MAX(A.version) version 6 from 7 junk A 8 , junk B 9 where 10 A.doc_num = B.doc_num 11 and A.title = B.title 12 and A.version >= B.version 13 group by 14 A.doc_num 15 ) C 16* where D.doc_num = C.doc_num and D.version = C.version
    ... bleh what a ugly mess.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://155114]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (2)
As of 2014-09-23 04:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (210 votes), past polls