views:

42

answers:

2

I have a simple MySQL query like:

SELECT * 
  FROM `content_category` CC , `content_item` CI 
 WHERE CI.content_id = '" . (int)$contentId . "'
   AND CI.category_id = CC.category_id
   AND CI.active  = 1

Both tables have a column called configuration one of which gets overwritten in the query i.e only content_item.configuration is returned in the result.

Short of implicitly naming and aliasing the columns like

SELECT CC.configuration as `category_configuration`,
       CC.category_id as `.....

is there a way of selecting ALL data i.e * from both and resolve those duplicate column names in a non-destructive way.

+2  A: 

You don't need to alias ALL the columns, just the one conflicting one:

SELECT *,CC.configuration as cc_conf, CI.configuration as ci_conf FROM `content_category` CC , `content_item` CI WHERE
CI.content_id = '" . (int)$contentId . "'
AND CI.category_id = CC.category_id
AND CI.active  = 1
Mike Sherov
That works well... it solves the problem of unique naming of the columns as many tables have columns with the same names where they hold json_encoded configuration data.
niggles
But those columns are still included in the set of columns returned by `*`. The aliased columns are duplicate, so you've doubled the amount of bytes for those columns that needs to pass over the network.
Bill Karwin
@bill, this is true, but I would consider that a microoptimization (unless the configs are huge) that comes at the expense of speed of implementation, and actually is a less cumbersome solution than the rest out there. Point well taken though.
Mike Sherov
I'm only getting 1 extra column returned i.e the second occurrence of `configuration` -> MySQLI seems to only return the second one as opposed to the PHP MyAdmin interface which returns both occurrences of it and hence the original question. The `config` column isn't huge anyway - half a dozen key/value pairs generally.
niggles
+1  A: 

This demonstrates one of the many reasons why using the * wildcard is not a good practice all the time. All the columns are returned in the result set, but if you access them via an associative array or via object properites in your host language (e.g. PHP or Ruby) you can naturally only have one of the columns associated with each key or object property.

Solutions:

  • Fetch them all and reference the columns by ordinal position.

  • Stop using the wildcard for one table or the other, and give column aliases.

  • Rename your columns to be distinct.

  • Define a VIEW with the column aliasing spelled out, and query from the view.

Bill Karwin
The * is (reasonably) necessary as this data is passed to a lot of functions and for the tradeoff of a larger result set v's adding new columns to the select each time I need to access a new column somewhere seemed to be ok.
niggles