RE: How to get hanging 1:M table rows as single column in main query?

2010-09-29 Thread Daevid Vincent
BRILLIANT

SELECT
`id_fmr`,
`fmr_number`,
`fmr_system`,
`fmr_station`,
`created_ts`,
 GROUP_CONCAT(`seat`)
FROM `fmr`
  JOIN `fmr_has_seat` USING (id_fmr)
  JOIN `dim_seat` USING (id_dim_seat)
WHERE id_fmr = 3
GROUP BY id_fmr;

id_fmr  fmr_number  fmr_system  fmr_station   created_ts
group_concat(`seat`)
--  --  --  ---  ---

 3  320237274 2333  JFK  2010-09-24 04:35:31
35C,35D,35E  

> -Original Message-
> From: Johnny Withers [mailto:joh...@pixelated.net] 
> Sent: Wednesday, September 29, 2010 1:35 PM
> To: Daevid Vincent
> Cc: MySQL
> Subject: Re: How to get hanging 1:M table rows as single 
> column in main query?
> 
> GROUP_CONCAT() ?
> 
> And group by id_fmr ?
> 
> JW
> 
> 
> On Wed, Sep 29, 2010 at 2:38 PM, Daevid Vincent 
>  wrote:
> 
> > Given three basic tables. An "fmr" table which has Field Maintenance
> > Reports, a Seat table and a "hanging" or "glue" table to 
> map Seats to FMRs.
> > [See below]
> >
> > How do I get all the Seats to be in a single "row" with the 
> FMR data?
> >
> > If I make this kind of query, they come in as separate rows:
> >
> > SELECT
> >`id_fmr`,
> >`fmr_number`,
> >`fmr_system`,
> >`fmr_station`,
> >`created_ts`,
> > `seat`
> > FROM `fmr`
> >  JOIN `fmr_has_seat` USING (id_fmr)
> >  JOIN `dim_seat` USING (id_dim_seat)
> > WHERE id_fmr = 3;
> >
> > id_fmr  fmr_number  fmr_system  fmr_station   
> created_ts  seat
> > --  --  --  ---  
> ---  
> > 3  320237274 2333  JFK  2010-09-24 04:35:31  35C
> > 3  320237274 2333  JFK  2010-09-24 04:35:31  35D
> > 3  320237274 2333  JFK  2010-09-24 04:35:31  35E
> >
> > I want something more like:
> >
> > id_fmr  fmr_number  fmr_system  fmr_station   
> created_ts  seat
> > --  --  --  ---  ---
> > ---
> > 3  320237274 2333  JFK  2010-09-24 04:35:31
> > 35C,35D,35E
> >
> >
> > Now, I'm going to be showing a few thousand FMR rows (and 
> ideally their
> > seats).
> >
> > What I do now is use PHP to pull the FMR records that match 
> a certain
> > criteria/filter.
> > Then I pull in the entire dim_seats as an array and store 
> it in a session
> > since it's not going to change ever. Then I loop over all 
> the id_fmr that I
> > have pulled and look up in the fmr_has_seat table by id_fmr 
> and implode()
> > the seats from the session array. It saves me a few joins 
> and gets the job
> > done, but I keep feeling like there's a better way to do it.
> >
> > I'm thinking there's some magic with a subselect and concat 
> or something in
> > SQL, but then I wonder if that's any more efficient as 
> mySQL still has to
> > do two SELECTs per FMR row. This feels to me like a common 
> problem and
> > there must be an optimal mySQL way of doing it. Hanging 
> tables of 1:M
> > relationships are used everywhere.
> >
> > 
> ==
> =
> > ==
> >
> > CREATE TABLE `fmr` (
> >  `id_fmr` int(11) NOT NULL auto_increment,
> >  `fmr_number` varchar(32) NOT NULL default '',
> >  `fmr_system` smallint(6) default NULL,
> >  `fmr_station` varchar(4) NOT NULL default '',
> >  `created_ts` timestamp NOT NULL default CURRENT_TIMESTAMP,
> >  PRIMARY KEY  (`id_fmr`)
> > ) ENGINE=InnoDB
> >
> > id_fmr  fmr_number  fmr_system  fmr_station created_ts
> > --  --  --  ---  ---
> > 1  319235F2A 2333  JFK  2010-09-24 04:35:31
> > 2  319235F29 2333  JFK  2010-09-24 04:35:31
> > 3  320237274 2333  JFK  2010-09-24 
> 04:35:31  <---
> > 4  32023726D 2333  JFK  2010-09-24 04:35:31
> > 5  32023725A 2333  JFK  2010-09-24 04:35:31
> > 6  32023724F 2333  JFK  2010-09-24 04:35:31
> > 7  320237241 2333  LAX  2010-09-24 04:35:31
> > 8  32023723A 2333  LAX  2010-09-24 04:35:31
> > 9  320237232 2333  JFK 

Re: How to get hanging 1:M table rows as single column in main query?

2010-09-29 Thread Johnny Withers
GROUP_CONCAT() ?

And group by id_fmr ?

JW


On Wed, Sep 29, 2010 at 2:38 PM, Daevid Vincent  wrote:

> Given three basic tables. An "fmr" table which has Field Maintenance
> Reports, a Seat table and a "hanging" or "glue" table to map Seats to FMRs.
> [See below]
>
> How do I get all the Seats to be in a single "row" with the FMR data?
>
> If I make this kind of query, they come in as separate rows:
>
> SELECT
>`id_fmr`,
>`fmr_number`,
>`fmr_system`,
>`fmr_station`,
>`created_ts`,
> `seat`
> FROM `fmr`
>  JOIN `fmr_has_seat` USING (id_fmr)
>  JOIN `dim_seat` USING (id_dim_seat)
> WHERE id_fmr = 3;
>
> id_fmr  fmr_number  fmr_system  fmr_station   created_ts  seat
> --  --  --  ---  ---  
> 3  320237274 2333  JFK  2010-09-24 04:35:31  35C
> 3  320237274 2333  JFK  2010-09-24 04:35:31  35D
> 3  320237274 2333  JFK  2010-09-24 04:35:31  35E
>
> I want something more like:
>
> id_fmr  fmr_number  fmr_system  fmr_station   created_ts  seat
> --  --  --  ---  ---
> ---
> 3  320237274 2333  JFK  2010-09-24 04:35:31
> 35C,35D,35E
>
>
> Now, I'm going to be showing a few thousand FMR rows (and ideally their
> seats).
>
> What I do now is use PHP to pull the FMR records that match a certain
> criteria/filter.
> Then I pull in the entire dim_seats as an array and store it in a session
> since it's not going to change ever. Then I loop over all the id_fmr that I
> have pulled and look up in the fmr_has_seat table by id_fmr and implode()
> the seats from the session array. It saves me a few joins and gets the job
> done, but I keep feeling like there's a better way to do it.
>
> I'm thinking there's some magic with a subselect and concat or something in
> SQL, but then I wonder if that's any more efficient as mySQL still has to
> do two SELECTs per FMR row. This feels to me like a common problem and
> there must be an optimal mySQL way of doing it. Hanging tables of 1:M
> relationships are used everywhere.
>
> ===
> ==
>
> CREATE TABLE `fmr` (
>  `id_fmr` int(11) NOT NULL auto_increment,
>  `fmr_number` varchar(32) NOT NULL default '',
>  `fmr_system` smallint(6) default NULL,
>  `fmr_station` varchar(4) NOT NULL default '',
>  `created_ts` timestamp NOT NULL default CURRENT_TIMESTAMP,
>  PRIMARY KEY  (`id_fmr`)
> ) ENGINE=InnoDB
>
> id_fmr  fmr_number  fmr_system  fmr_station created_ts
> --  --  --  ---  ---
> 1  319235F2A 2333  JFK  2010-09-24 04:35:31
> 2  319235F29 2333  JFK  2010-09-24 04:35:31
> 3  320237274 2333  JFK  2010-09-24 04:35:31  <---
> 4  32023726D 2333  JFK  2010-09-24 04:35:31
> 5  32023725A 2333  JFK  2010-09-24 04:35:31
> 6  32023724F 2333  JFK  2010-09-24 04:35:31
> 7  320237241 2333  LAX  2010-09-24 04:35:31
> 8  32023723A 2333  LAX  2010-09-24 04:35:31
> 9  320237232 2333  JFK  2010-09-24 04:35:31
>10  320237230 2333  JFK  2010-09-24 04:35:31
> ....   ..   ..   ..
>
> CREATE TABLE `fmr_has_seat` (
>  `id_fmr` int(11) NOT NULL auto_increment,
>  `id_dim_seat` int(10) unsigned NOT NULL,
>  PRIMARY KEY  (`id_fmr`,`id_dim_seat`),
>  KEY `id_dim_seat` (`id_dim_seat`),
>  CONSTRAINT `fmr_has_seat_ibfk_1` FOREIGN KEY (`id_fmr`) REFERENCES `fmr`
> (`id_fmr`) ON DELETE CASCADE ON UPDATE CASCADE,
>  CONSTRAINT `fmr_has_seat_ibfk_2` FOREIGN KEY (`id_dim_seat`) REFERENCES
> `dim_seat` (`id_dim_seat`) ON DELETE CASCADE ON UPDATE CASCADE
> ) ENGINE=InnoDB
>
> id_fmr  id_dim_seat
> --  ---
> 3  888 <---
> 3  889 <---
> 3  890 <---
> 4  422
> 4  423
> 4  551
> 4  552
> 4  553
> 5  420
> 5  550
> 5  628
> 5  629
> 5  706
> 5  707
> 5  811
>  ...   ...
>
> CREATE TABLE `dim_seat` (
>  `id_dim_seat` int(10) unsigned NOT NULL auto_increment,
>  `seat` varchar(4) default NULL,
>  PRIMARY KEY  (`id_dim_seat`),
>  KEY `seat` (`seat`)
> ) ENGINE=InnoDB
>
> id_dim_seat  seat
> ---  --
>  ...  ...
>888  35C  <---
>889  35D  <---
>890  35E  <---
>891  35F
>892  35G
>...  ...
>
>
> --
> MySQL General Mailing List
> For list archives: http://lists.mysql.com/mysql
> To unsubscribe:http://lists.mysql.com/mysql?unsub=joh...@pixelated.net
>
>


-- 
-
Johnny Withers
601.209.4985
joh...@pixelated.net