views:

159

answers:

5

Working on parsing a bunch of databases put together in an older, more freewheeling time into a new schema. Basically it's one database per year, with database names like foo98, foo99, foo2000, etc.

So for the most recent foo data, I can do something like

SELECT foo_person.mdname AS middle_name,
...
FROM foo_person, foo_place, foo_thing

As you get back into earlier versions of the foo database, middle name isn't stored. I've tried to build a kind of universal query, something like:

SELECT IFNULL(foo_person.mdname, "") AS middle_name,
...
FROM foo_person, foo_place, foo_thing

but MySQL complains about unknown column foo_person.mdname, which is entirely reasonable as it doesn't exist.

Is there some way to handle non-existent columns with just MySQL syntax, or will I have to write database-specific import queries?

A: 

If you're working with heterogenous databases, I would use database-specific import queries anyways. You might need to join some columns and remove some, and truncate some, etc.

Paul Tarjan
+2  A: 

There isn't any way of handling a non-existent column in sql (as opposed to an empty column).

You can tell whether the column is there or not using the information_schema tables, like so:

select * from information_schema.columns
    where table_name='mytable' and table_schema='mydatabase';
ʞɔıu
+1  A: 

Yes there is a way.

Let's consider these databases

  • DB2009 has Person with Fname, MInitial and LName
  • DB2008 has Person with Fname and LName
  • DB2007 has Person with PersonName

You can do something similar the following (I wrote this for MS SQL Server)

/*all three columns exist*/
SELECT FName, MInitial, LName
From DB2009.Person

UNION

/*one column is a forced null */
SELECT FName, NULL as MInitial, LName
From DB2008.Person

UNION

/*two columns are derived and one column is a forced null */
SELECT SubString (1, CharIndex (PersonName, ' '), PersonName) as FirstName,
       NULL as MInitial, 
       SubString (CharIndex (PersonName, ' '), len (PersonName), PersonName),
From DB2007.Person
Raj More
+1  A: 

Could you rename the tables and create views in their place with the missing columns?

Not sure if this is what you're looking for, but thought I would suggest it.

-- Here is your original table
create table t (fname varchar(30), lname varchar(30));

-- Rename it to something else
alter table t rename to tOrig;

-- Create a view with the columns its missing that you need
create view t as select fname, lname, '' as mname from tOrig;
RC
Yes, actually, this works quite well. They're old databases and the one thing I can be sure of is that nothing is pointing at them anymore. Thanks for the lateral thinking.
Glazius
No problem. Glad it worked out for you.
RC
A: 

Instead of making more complex sql queries, perhaps it would be better to alter the foo98 and foo99 tables to add in the missing columns.

For example, to add a column of type varchar(30) called "mdname" to foo98:

ALTER TABLE foo98 ADD mdname varchar(30) AFTER first_name;

Then you can relax and use the same simple SQL query no matter which tabel is being accessed.

unutbu