Categories: MSDN / DotNet / Java / Scripts / Linux / PHP Ask - La ask - La Answer

Converting Flat Table to Relational

Hi,

I have a big table, with a bunch of data in it. but they get pretty big being they are flat instead of relational.

I am taking this data and dividing it into 3 tables. I have populated the first two tables with data from the 3rd.

this is the structure of the 2 tables:

CREATE TABLE TI (
[TI_id] COUNTER,
[PN] TEXT(16),
[Start_Date] DATE,
[Start_Time] TIME,
[TT(min)] SINGLE,
[TB] TEXT(22),
[SN] TEXT(32),
[C1] TEXT(32),
[TestStand] TEXT(24),
[TP] TEXT(32),
[CalFile] TEXT(72),
PRIMARY KEY (PN,Start_Date,Start_Time,TestStand)
);

CREATE TABLE TS (
[TS_id] COUNTER,
[T(C)] SINGLE,
[TPG] TEXT(16),
[RFPath] TEXT(16),
[Mode] TEXT(16),
[RFMod] TEXT(16),
[F(MHz)] SINGLE,
[Vcc(V)] SINGLE,
[Vr(V)] SINGLE,
[DCVr(%)] SINGLE,
PRIMARY KEY ([T(C)],[TPG],[RFPath],[Mode],[RFMod],[F(MHz)],[Vcc(V)],[Vr(V)],[DCVr(%)])
);

now...in the 3rd table, what i want to do is whereever the fields line up for a unique TS_id or TI_id, to update the table with those unique values.

after this is done, i will DROP all those fields that are redundant, to leave only the other fields that i need, and the TS_id and TI_id.

thereby greatly reducing my overhead.

(although it wont be as relational as it can be...but it's definitely a step).

is there a good way to create a query to do this?

record by record would take forever.

fyi
table TI has 30 rows
table TS has 726 rows
and data table still has like 347,000 rows, with all of the redundant TI and TS data included. (this is a small database, for testing. the real deal will be bigger)

If you have any ideas, I'd be glad to hear them. I'm not very good with complicated SQL queries.

Thanks!
[1901 byte] By [chupacabra] at [2007-11-11 10:29:35]
# 1 Re: Converting Flat Table to Relational
I could loop through the records in the TI table, updating the data table TI_id where the fields are = with the unique id from the TI table.

then the same thing w/ the TS table.

but is there a better way?
chupacabra at 2007-11-11 23:43:21 >
# 2 Re: Converting Flat Table to Relational
I am revisiting this. Actually finally getting around to the real thing.

here is my other thread in the VB6 forum for reference: http://forums.dev-archive.com/showthread.php?t=161135

I'm posting here again because I think this may be more database related than VB related.
I will copy my last couple of posts to make this easier.

I think I have done some of this. let me know if i am on the right track.

for instance, the format of my data:

id1 - field1a - field1b - field1c - id2 - field2a - field2b - field2c - id3 - fielda - field3b - field3c - field3d - field3e

''
id1 is thrown away, more of a marker. it is the same (=1) all the way through the text file. field1a, bc, are all a unique record in an info table.

so i could mass copy this chunk into the other table, then drop these columns from the temp table and update the marker ID columns with the real values.

''

id2 is also another marker, same all through. these fields are in a stimulus column, but up and down, into two tables. one is a list.

To do this...I would have to go record by record in the temp table, and then go left to right on each record through each field. right? or is there a better way? this is where i get kinda lost, and seems like it will crunch REALLY slow

id - Parameter - value

listid - paramID

'''

id3 is another marker, but the data behind it is also put in the vertical format
data_id - Info_id - stimListID - parameter - value

----

hello. i'm just now getting around to working on this.

with the crosstab query, can i do the opposite of that?

my data looks like the second example above (what I call horizontal).
and I am trying to get it similar to the first example (what I call vertical).

My data look like this (horizontal):

Temperature,Status,Mode,Voltage
-----------
25,On,RF,12

I want it to be (vertical):

ID,Parameter,Value
-------
1,Temperature,25
2,Status,On
3,Mode,RF
4,Voltage,12

many more fields, but for example. :)

Thanks for your help

anybody have any ideas? good ways to go about this?

I have 13 fields across to split into another table. And then between 20 and 30 fields to go into another table in this manner.
chupacabra at 2007-11-11 23:44:21 >
# 3 Re: Converting Flat Table to Relational
The only thing I can think of us to use a different query to handle each column. Like:
INSERT INTO vParms (Parameter, Value)
SELECT "Temperature" As Parameter, [Temperature] As Value From hParms;

INSERT INTO vParms (Parameter, Value)
SELECT "Status" As Parameter, [Status] As Value From hParms;

INSERT INTO vParms (Parameter, Value)
SELECT "Mode" As Parameter, [Mode] As Value From hParms;

INSERT INTO vParms (Parameter, Value)
SELECT "Voltage" As Parameter, [Voltage] As Value From hParms;

If you are going to use this alot you coukd create a untion query as a base for your update query like:
Update Query -> qup_vParms:
INSERT INTO vParms (Parameter, Value)
SELECT Parameter, Value From qun_hParms;

Union Query -> qun_hParms:
SELECT "Temperature" As Parameter, [Temperature] As Value From hParms
UNION SELECT "Status" As Parameter, [Status] As Value From hParms
UNION SELECT "Mode" As Parameter, [Mode] As Value From hParms
UNION SELECT "Voltage" As Parameter, [Voltage] As Value From hParms;
Ron Weller at 2007-11-11 23:45:16 >
# 4 Re: Converting Flat Table to Relational
Ok, that may work. Definitely better than the way I was doing it in my first draft...hahaha.

I was going from row to row, and column to column in each row...took forever. literally. At the time I knew it was dumb, but it was just a test.

I'll give it a try in the way you suggested, I think it may just work that way.

Maybe one day I'll get this project done, I keep getting pulled off to do other things, then basically just work on this in the spare time (what spare time?)

thanks again! :)
chupacabra at 2007-11-11 23:46:16 >
# 5 Re: Converting Flat Table to Relational
The only thing I can think of us to use a different query to handle each column. Like:
INSERT INTO vParms (Parameter, Value)
SELECT "Temperature" As Parameter, [Temperature] As Value From hParms;

INSERT INTO vParms (Parameter, Value)
SELECT "Status" As Parameter, [Status] As Value From hParms;

INSERT INTO vParms (Parameter, Value)
SELECT "Mode" As Parameter, [Mode] As Value From hParms;

INSERT INTO vParms (Parameter, Value)
SELECT "Voltage" As Parameter, [Voltage] As Value From hParms;

If you are going to use this alot you coukd create a untion query as a base for your update query like:
Update Query -> qup_vParms:
INSERT INTO vParms (Parameter, Value)
SELECT Parameter, Value From qun_hParms;

Union Query -> qun_hParms:
SELECT "Temperature" As Parameter, [Temperature] As Value From hParms
UNION SELECT "Status" As Parameter, [Status] As Value From hParms
UNION SELECT "Mode" As Parameter, [Mode] As Value From hParms
UNION SELECT "Voltage" As Parameter, [Voltage] As Value From hParms;

the one question i have, is how can i store the qun_hparms to be called...

basically how can i execute/generate this query in VB?
chupacabra at 2007-11-11 23:47:26 >
# 6 Re: Converting Flat Table to Relational
Through Automation. You will have to create an Access Application object that then opens the correct database. From there you will need to access the applications currentDb object, which in turn gives you access to the QueryDefs collection.
All of this requires that you add the Microsoft Access Objects Library to your project references.
Below is a code sample for creating and editing a query. This was done in Access so once you have created your Access Application Object variable and have opened the database the code here will work with minor modifications. Just by adding your Access Object Variable, call is accApp, in front of any CurrentDb references will make this work in VB as well. So for example: CurrentDb.QueryDefs.Append qd
' -> becomes:
accApp.CurrentDb.QueryDefs.Append qd
Here is the sample code:Sub makqun()
Dim qd As QueryDef
Dim sql As String

'as a test just put the first two queries in the new querydef
'run it the first time creates it with the first two queries
'run it a second time adds in the other two queries
sql = "SELECT ""Temperature"" As Parameter, [Temperature] As Value From hParms" & vbCrLf & _
"UNION SELECT ""Status"" As Parameter, [Status] As Value From hParms" & vbCrLf
On Error Resume Next
'see if it already exsists
Set qd = CurrentDb.QueryDefs("qun_hParms")
If qd Is Nothing Then
'it did not exsist so create a new one
Set qd = New QueryDef
qd.Name = "qun_hParms"
qd.sql = sql
'append new querydef to the querydefs collection
CurrentDb.QueryDefs.Append qd
Else
'query already exsisted so I could change it right here

'here is the add in of the other two queries
sql = sql & "UNION SELECT ""Mode"" As Parameter, [Mode] As Value From hParms" & vbCrLf & _
"UNION SELECT ""Voltage"" As Parameter, [Voltage] As Value From hParms;"
qd.sql = sql
End If
'all done so release memory for querydef object
Set qd = Nothing
End Sub
Ron Weller at 2007-11-11 23:48:19 >
# 7 Re: Converting Flat Table to Relational
that answered my question exactly!

thanks, ron!

I should have this project done in no time, now :D (assuming access doesn't crash, haha)
chupacabra at 2007-11-11 23:49:28 >
# 8 Re: Converting Flat Table to Relational
what do i DIM the qd as?

querydef is undefined datatype. I am using ADO, is that part of the DAO library maybe?

i added this:
Dim accApp As Application
chupacabra at 2007-11-11 23:50:20 >
# 9 Re: Converting Flat Table to Relational
No, DAO is like ADO they are both for data access.
You need the Microsoft Access ?.? Objects Library where the ?.? is the version like 9.0 Dim accApp As Access.Application

' Create new hidden instance of Access.
Set accApp = New Access.Application
' Show this instance of Access.
accApp.Visible = True
Ron Weller at 2007-11-11 23:51:28 >
# 10 Re: Converting Flat Table to Relational
i have added the access objects 11.0 reference

but the querydef is not defined

I was reading this link:
http://p2p.wrox.com/topic.asp?TOPIC_ID=3746
that's why i was thinking maybe it was specific to DAO

The other fundamental difference is that ADO introduces a Command object to represent a SQL statement or stored procedure. The Command object is the ADO replacement for DAOs QueryDef object, and lets you execute DDL and DML commands on a conncetion.

my accApp is declared right now, though. :)
chupacabra at 2007-11-11 23:52:26 >
# 11 Re: Converting Flat Table to Relational
Looks like VB does not like the idea of creating an empty querydef, setting it's properties, and then appending it to the querydefs collection. No worries you can use the CreateQueryDef() function instead. You will also need to add the references for the DAO, Data Access Objects, as well. QueryDef Objects are part of the DAO Objects Library. It's ok to have both DAO and ADO libraries in your references. Some objects are the same in both so when you define them you should qualify them with either DAO or ADODB. I even do this on objects that exist in only one library, to help document where the object definition came from. Example: Dim rsDao As DAO.Recordset
Dim rsAdo As ADODB.Recordset
Dim qd As DAO.QueryDefHere is a revised version that actually works in vb. Sorry I could not do this for you before; but I was at work and I don't have VB at work, just MS Access:Sub makqun()
Dim qd As DAO.QueryDef
Dim sql As String

Dim accApp As Access.Application
' Create new hidden instance of Access.
Set accApp = New Access.Application
' Show this instance of Access.
'accApp.Visible = True

accApp.OpenCurrentDatabase App.Path & "\db1.mdb"


'as a test just put the first two queries in the new querydef
'run it the first time creates it with the first two queries
'run it a second time adds in the other two queries
sql = "SELECT ""Temperature"" As Parameter, [Temperature] As Value From hParms" & vbCrLf & _
"UNION SELECT ""Status"" As Parameter, [Status] As Value From hParms" & vbCrLf
On Error Resume Next
'see if it already exsists
Set qd = accApp.CurrentDb.QueryDefs("qun_hParms")
On Error GoTo 0
If qd Is Nothing Then
Set qd = accApp.CurrentDb.CreateQueryDef("qun_hPArms", sql)
Else
'query already exsisted so I could change it right here

'here is the add in of the other two queries
sql = sql & "UNION SELECT ""Mode"" As Parameter, [Mode] As Value From hParms" & vbCrLf & _
"UNION SELECT ""Voltage"" As Parameter, [Voltage] As Value From hParms;"
qd.sql = sql
End If
'all done so release memory for querydef object
Set qd = Nothing

accApp.Quit
Set accApp = Nothing

End Sub
Ron Weller at 2007-11-11 23:53:30 >
# 12 Re: Converting Flat Table to Relational
oh no problem, i was just kinda mixed up with it. I don't really know much at all about DAO. I've always declared my ado stuff as ADODB.<whatever>, just figured it was good practice.

thanks for all the help

I'll use this code you've given me, hopefully i can get it to work with this database i'm doing. I'll have to modify it to load all my fields...they vary, sometimes only like 30 fields, and sometimes more like 40 or 50. sucks but that's how it goes w/ this kind of data.

my NEXT question is...is it possible to do these queries in another way, without using access, like just SQL?

If/when I migrate to a bigger server and start using another database engine (like SQLServer or MySQL), i want to be able to re-use as much code as possible so i wont have to redo everything.

is there a good SQL resource or something that I can read through? I'm decent with SQL, but when it gets to the really complicated kind of stuff, i'm not too confident with it (yet)

Thanks again!
chupacabra at 2007-11-11 23:54:33 >
# 13 Re: Converting Flat Table to Relational
is there a good SQL resource or something that I can read through?Here are some links that you might find interesting.

http://www.sqlcourse2.com/
http://www.smart-soft.co.uk/Oracle/advanced-sql-tutorial.htm
http://www.1keydata.com/sql/advanced.html
Hack at 2007-11-11 23:55:34 >
# 14 Re: Converting Flat Table to Relational
Here are some links that you might find interesting.

http://www.sqlcourse2.com/
http://www.smart-soft.co.uk/Oracle/advanced-sql-tutorial.htm
http://www.1keydata.com/sql/advanced.html

thanks!

btw (OT), Justlinux.com is the sister site to this one? I LOVE that site, I've been on there for years, longer than i've been on here! never even knew
chupacabra at 2007-11-11 23:56:29 >
# 15 Re: Converting Flat Table to Relational
btw (OT), Justlinux.com is the sister site to this one? Yep...Jupitermedia owns a wide variety of sites, not just this one and JustLinux. JM pretty much covers the entire forum site spectrum. :)
Hack at 2007-11-11 23:57:29 >
# 16 Re: Converting Flat Table to Relational
my NEXT question is...is it possible to do these queries in another way, without using access, like just SQL?

If/when I migrate to a bigger server and start using another database engine (like SQLServer or MySQL), i want to be able to re-use as much code as possible so i wont have to redo everything.

is there a good SQL resource or something that I can read through? I'm decent with SQL, but when it gets to the really complicated kind of stuff, i'm not too confident with it (yet)
Yes absolutly! The only reason you needed Access in this example was because you wanted to create and store the query in vb. If you just need to build and execute the query without saving the actual query in access then you don't need to use Automation i.e. (Access Objects Library) at all.
The basic steps are fairly simple. For each different database you create an ado connection object and open a connection to that database. I usually open my connection objects at the very beginning of my program and don't close them until the very end when my application is terminating. This way I have access to the connection objects throughout the app and I don't have to open and close them every time I need them.
With these connection objects you can use them when you create and open recordsets. Recordsets are used for running your queries. You take the sql text, just like you did in this thread, but now you use it in the Recordset.Open function. The Open function executes the SQL in your String variable. Once the recordset is open you can move through it and access each field of each record. You can edit and update the fields of each record, add new records, etc... If you goto www.freevbcode.com and search on ADO you will find lots of samples that will show you exactly how to do this.
As far as SQL goes, what I did when I first started with SQl was to build my queries in the Access query designer, also I could make sure they work, and then switch to SQL View, copy and paste the sql into my VB app. Once you paste it into VB you will need to store it as a string in a variable like we did with the Sql string variable in the previous posts. As you do this more and more and begin to edit the SQL even after building it in Access you will very quickly pickup on the SQL syntax. Just be aware that every database system has a different variation on it's implimentation of SQL. You will need to edit your SQL strings to fit the particular database system.
Ron Weller at 2007-11-11 23:58:33 >
# 17 Re: Converting Flat Table to Relational
Sorry Ron, maybe I gave the wrong impression. I've programmed with ADO for a while, but missed the DAO bandwagon I guess. That is all very good info though. :)

that's why i didnt really want to add the DAO references, trying to keep my executable as small as possible.

I meant as far as making the Union query one big long query, instead of calling another query...

INSERT INTO vParms (Parameter, Value)
SELECT "Temperature" As Parameter, [Temperature] As Value From hParms;

INSERT INTO vParms (Parameter, Value)
SELECT "Status" As Parameter, [Status] As Value From hParms;

INSERT INTO vParms (Parameter, Value)
SELECT "Mode" As Parameter, [Mode] As Value From hParms;

INSERT INTO vParms (Parameter, Value)
SELECT "Voltage" As Parameter, [Voltage] As Value From hParms;

If you are going to use this alot you coukd create a untion query as a base for your update query like:
Update Query -> qup_vParms:
INSERT INTO vParms (Parameter, Value)
SELECT Parameter, Value From qun_hParms;

Union Query -> qun_hParms:
SELECT "Temperature" As Parameter, [Temperature] As Value From hParms
UNION SELECT "Status" As Parameter, [Status] As Value From hParms
UNION SELECT "Mode" As Parameter, [Mode] As Value From hParms
UNION SELECT "Voltage" As Parameter, [Voltage] As Value From hParms;

would that be like this (or something like this?):

INSERT INTO vParms (Parameter, Value)
SELECT "Temperature" As Parameter, [Temperature] As Value From
(
SELECT "Temperature" As Parameter,
UNION SELECT "Status" As Parameter,
UNION SELECT "Mode" As Parameter,
UNION SELECT "Voltage" As Parameter,
<etc...>
);
chupacabra at 2007-11-11 23:59:35 >
# 18 Re: Converting Flat Table to Relational
Sure! 'A Make-Table query would be more like this:
SELECT * INTO vParms
FROM (SELECT "Temperature" As [Parameter], [Temperature] As [Value] From hParms
UNION SELECT "Status" As [Parameter], [Status] As [Value] From hParms
UNION SELECT "Mode" As [Parameter], [Mode] As [Value] From hParms
UNION SELECT "Voltage" As [Parameter], [Voltage] As [Value] From hParms
) AS xParms;

'And An Append Query would look like this:

INSERT INTO vParms
SELECT *
FROM (SELECT "Temperature" As [Parameter], [Temperature] As [Value] From hParms
UNION SELECT "Status" As [Parameter], [Status] As [Value] From hParms
UNION SELECT "Mode" As [Parameter], [Mode] As [Value] From hParms
UNION SELECT "Voltage" As [Parameter], [Voltage] As [Value] From hParms
) AS xParms;
Ron Weller at 2007-11-12 0:00:34 >
# 19 Re: Converting Flat Table to Relational
You can even create a select query that looks like this:SELECT *
FROM (SELECT "Temperature" As [Parameter], [Temperature] As [Value] From hParms
UNION SELECT "Status" As [Parameter], [Status] As [Value] From hParms
UNION SELECT "Mode" As [Parameter], [Mode] As [Value] From hParms
UNION SELECT "Voltage" As [Parameter], [Voltage] As [Value] From hParms
) AS xParms;

'Final Result:
Parameter Value
Mode RF
Status On
Temperature 25
Voltage 12
Ron Weller at 2007-11-12 0:01:32 >
# 20 Re: Converting Flat Table to Relational
awesome, thanks!

another question though...in this query I want to take the first section of the flat table, and put into it's table (TI). I want to update the TI_id fields in the flat table to be = to the distinct values in the TI table.

For instance, there may be 500,000 rows in the flat table. if I take a "DISTINCT" of just the TI fields that are in the flat table, there may only be 10 unique. So i'm updating the ID field in the flat table w/ the id fields from the TI table where the other fields match.

is my WHERE statement in the correct place?

'tablefields() array of the fields in the TI table
query = "UPDATE " & DATATABLE & vbCrLf & " SET [" & DATATABLE & "].[TI_id] = " & vbCrLf & "(SELECT [TI_id] FROM TI "
query = query & "WHERE (" & vbCrLf
For i = 0 To intfields Step 1
If UCase(tableFields(i)) = TI_id Then i = i + 1
query = query & vbTab & "[TI].[" & tableFields(i) & "] = [" & DATATABLE & "].[" & tableFields(i) & "] "
If Not i = intfields Then query = query & ", " & vbCrLf & vbTab
Next i
query = query & ")" & vbCrLf & ");"

?query
UPDATE DATA_WLAN
SET [DATA_WLAN].[TI_id] =
(SELECT [TI_id] FROM TI WHERE (
[TI].[C1] = [DATA_WLAN].[C1],
[TI].[CalFile] = [DATA_WLAN].[CalFile],
[TI].[PN] = [DATA_WLAN].[PN],
[TI].[SN] = [DATA_WLAN].[SN],
[TI].[Start_Date] = [DATA_WLAN].[Start_Date],
[TI].[Start_Time] = [DATA_WLAN].[Start_Time],
[TI].[TB] = [DATA_WLAN].[TB],
[TI].[TestStand] = [DATA_WLAN].[TestStand],
[TI].[TP] = [DATA_WLAN].[TP],
[TI].[TT(min)] = [DATA_WLAN].[TT(min)])
);
chupacabra at 2007-11-12 0:02:39 >
# 21 Re: Converting Flat Table to Relational
I'm an idiot. nevermind. haha.

?query
UPDATE DATA_WLAN, TI
SET [DATA_WLAN].[TI_id] = [TI].[TI_id]
WHERE (
[TI].[C1] = [DATA_WLAN].[C1] AND
[TI].[CalFile] = [DATA_WLAN].[CalFile] AND
[TI].[PN] = [DATA_WLAN].[PN] AND
[TI].[SN] = [DATA_WLAN].[SN] AND
[TI].[Start_Date] = [DATA_WLAN].[Start_Date] AND
[TI].[Start_Time] = [DATA_WLAN].[Start_Time] AND
[TI].[TB] = [DATA_WLAN].[TB] AND
[TI].[TestStand] = [DATA_WLAN].[TestStand] AND
[TI].[TP] = [DATA_WLAN].[TP] AND
[TI].[TT(min)] = [DATA_WLAN].[TT(min)]
);
chupacabra at 2007-11-12 0:03:43 >
# 22 Re: Converting Flat Table to Relational
update: the union select query worked great!

However now i'm completely confused as to how to do the next step... :confused: :(

I have populated my TS table. Now, I just need to populate the TS_set table and add those ID's to the flat DATA table before i move the data itself out w/ another union select query.

here is my db structure for reference:

First:

a testinfo table which is simple and just contains basic information.
(which I'm not including, because it's just easy as is)

Next:

CREATE TABLE TS (
[TS_id] COUNTER,
[Param] Text(8),
[nValue] SINGLE,
[sValue] Text(16),
PRIMARY KEY ([Param],[nValue],[sValue])
);

This table will contain a complete list of all of the parameters with distinct values. There are a fininte number of these.

a combination of several (5-10) of these parameters is a "set" of Test stimuli... a lsit of which is being stored in another table:

CREATE TABLE TS_Set (
[TSSet_id] COUNTER,
[TS_id] LONG,
PRIMARY KEY ([TSSet_id], [TS_id])
);

for example.
----------------
TS
id param nvalue svalue
1 temp 25 (null)
2 time 2150 (null)
3 mod (null) a180

TS_Set
set_id ts_id
1 1
1 2
1 3

------------------

Last, but not least. the actual data, which is lots and lots of rows, and is certainly one huge table.

CREATE TABLE DATA (
[Data_id] COUNTER,
[TI_id] LONG,
[TSSet_id] LONG,
[Param] TEXT(16),
[Value] DOUBLE,
PRIMARY KEY (TI_id,TSSet_id,Param)
);
chupacabra at 2007-11-12 0:04:41 >
# 23 Re: Converting Flat Table to Relational
maybe i could make a temp table that looks like this:

CREATE TABLE tempTS (
[TS_id] COUNTER,
[TEMP] SINGLE,
[TPG] TEXT(8),
[PATH] TEXT(16),
[VCC] DOUBLE,
<... and etc through all of the stimuli ...>
PRIMARY KEY (...all of stimuli...)
);

and then work on it that way...

is there a better way?
chupacabra at 2007-11-12 0:05:36 >