[DB-SIG] Mysql query

Andy Todd andy47 at halfcooked.com
Thu Aug 3 00:25:38 CEST 2006


Patricia wrote:
> Hi all,
> 
> I'm having a hard time trying to create this query.
> I have two tables:
> log - columns: id, name and date
> info - columns: id, tag, value
> 
> i.e.:
> log
> id | name                  | date
> -------------------------------------
> 1  | machine_name          | 07/31/06
> 2  | another_machine_name  | 08/01/06
> 
> info
> id  | tag       | value
> --------------------------------
> 1   | release   | release_name
> 1   | arch      | 32-bit
> 1   | mode      | amode
> 2   | release   | release_name
> 2   | arch      | 64-bit
> 2   | mode      | amode
> 
> Basically, the info table contains detailed information of 
> each machine in the log table. The same machine can appear 
> more than once, but with a different id number, that's why
> I use group by in the following query:
> 
>  select lo.name, inf.value, lo.date from log as lo 
>  join info as inf on lo.id=inf.id where (inf.tag='release' 
>  and inf.tag='arch') AND lo.id in (select max(id) 
>  from log group by name) order by name
> 
> Everything worked well, but now I've been asked to display
> this data based on "mode" (located in the info table). 
> I don't have to display mode, but I have to use it as 
> a condition since there are more than two modes. 
> I'm not sure how to add this condition to the query, though. 
> I tried adding this to the query above but, of course, 
> it didn't work:
>  
>  AND inf.id in (select id from info where value LIKE %s)
> 
> I'd appreciate any help
> Thanks,
> Patricia
> 
> 
> 
> _______________________________________________
> DB-SIG maillist  -  DB-SIG at python.org
> http://mail.python.org/mailman/listinfo/db-sig

Patricia,

This isn't a Python or MySQL problem, it's an issue with your schema
design. You need to change your schema. You could change your info table
to something less generic like;

id |  release     | arch   | mode
----------------------------------
1  | release_name | 32-bit | amode
2  | release_name | 64-bit | amode
3  | release_name | 64-bit | amode

This will make your initial query a lot simpler, something like;

select lo.name, inf.release, inf.arch, inf.mode, lo.date
from log as lo
      join info as inf on lo.id=inf.id
where lo.id in (select max(id)
                 from log group by name)
order by name

You could make it even simpler by putting a 'latest' flag on your log
table, e.g

id | name                  | date     | latest
----------------------------------------------
1  | machine_name          | 07/31/06 | Y
2  | another_machine_name  | 08/01/06 | N
3  | another_machine_name  | 08/02/06 | Y

then your query could look something like;

select lo.name, inf.release, inf.arch, inf.mode, lo.date
from log as lo
      join info as inf on lo.id=inf.id
where lo.latest = 'Y'
order by name

Having a generic table with key value pairs like your current info table
just leads to some really horrible SQL as you are currently finding. 
Unless you truly don't know what key-value pairs you are going to store 
it's always best to design your table to store the specific values you 
are going to store.

Regards,
Andy
-- 
--------------------------------------------------------------------------------
 From the desk of Andrew J Todd esq - http://www.halfcooked.com/




More information about the DB-SIG mailing list