nasty query

Corticus

Well-known Member
Joined
Apr 30, 2002
Messages
1,579
Hi all,

I've got a nasty query to do.

In short, I need to make this:
Book1
ABCD
1NameServiceIDServiceNameRate
2Alachua1HDM5.5
3Alachua2CM5.1
4Alachua3EAR4.8
5Citrus1HDM6.7
6Citrus2EAR3.9
7Columbia1HDM2.4
8Columbia2EAR7.6
9Columbia3CM3.4
10Columbia4PECA4.5
Sheet1


become this:
Book1
FGHIJKLMN
1NameServ1Rate1Serv2Rate2Serv3Rate3Serv4Rate4
2AlachuaHDM5.5CM5.1EAR4.8
3CitrusHDM6.7EAR3.9
4ColumbiaHDM2.4EAR7.6CM3.4PECA4.5
Sheet1


Which I have sort of figured out how to do. I can make the query work as long as I know the max number of services, with SQL like:
SELECT QryRates.Name, QryRates.County, QryRates.ServiceName AS Serv1, QryRates.BillableRate AS Rate1, QryRates_1.ServiceName AS Serv2, QryRates_1.BillableRate AS Rate2, QryRates_2.ServiceName AS Serv3, QryRates_2.BillableRate AS Rate3
FROM (QryRates INNER JOIN QryRates AS QryRates_1 ON QryRates.Name = QryRates_1.Name) INNER JOIN QryRates AS QryRates_2 ON QryRates_1.Name = QryRates_2.Name
WHERE (((QryRates.ServiceID)=1) AND ((QryRates_1.ServiceID)=2) AND ((QryRates_2.ServiceID)=3));

But if there is no service 3, then the query return no records, since the "3" criteria for serv3 is not met,since there are no service 3.

Oh, what to do.

Thanks!

I apologize for the hideous SQL, but I wanted to show that I had done something to try to do this.
 

Excel Facts

Difference between two dates
Secret function! Use =DATEDIF(A2,B2,"Y")&" years"&=DATEDIF(A2,B2,"YM")&" months"&=DATEDIF(A2,B2,"MD")&" days"
Hi Corticus,

That is a tough one. I think you're going to have to use code.

If this is a one-time thing, then I would look for the maximum number in the ServiceID field, and then make your table (create a new table) with that many ServX and RateX fields. Then loop through the recordset of the original table - put the "Name" field into a temporary variable, then check it to the current record to see if you should still be filling in field values for the same "Name" as the last record. Does that make sense? So you'll be looping through 2 recordsets at once.

So it might look somthing like (aw heck, I wrote the code):
Code:
Sub Transpose2()
    ' Russell Hauf, June 11, 2003 for MrExcel Message Boards
    
    Dim strLastName As String
    
    Dim rstNew As New ADODB.Recordset
    Dim rstOld As New ADODB.Recordset
    
    
    rstNew.Open "tbl061103b", CurrentProject.Connection, adOpenDynamic, adLockOptimistic
    rstOld.Open "Select * from tbl061103 order by Name", CurrentProject.Connection, adOpenForwardOnly, adLockOptimistic

    Do While Not rstOld.EOF
        If strLastName <> rstOld.Fields("Name") Then
            rstNew.AddNew
            rstNew.Fields("Name") = rstOld.Fields("Name")
            strLastName = rstOld.Fields("Name")
        End If
        rstNew.Fields("Serv" & rstOld.Fields("ServiceID")) = rstOld.Fields("ServiceName")
        rstNew.Fields("Rate" & rstOld.Fields("ServiceID")) = rstOld.Fields("Rate")
        rstNew.Update
        rstOld.MoveNext
    Loop

End Sub

Make sure you order by the name when you open the recordset, because even if it looks like the table is sorted by name, the recordset based on the table may not be. My "old" table is named tbl061103, and the new one is tbl061103b.

HTH,

Russell

p.s. If you're going to be doing this on a regular basis, you could create the table dynamically in code - just use DMAX to find the highest ServiceID, and make that many Serv and Rate fields in the new table, then run the code above.
 
Upvote 0
That's nice Russel, thanks.

This is probably going to be long...sorry...

I was hoping I wouldn't have to get into it to much just because its boring, but I guess details are necessary. The query has to get run every time a certain database is opened. The database is serving as storage for the data for a mail merge in Word. Word will only break your sections up by records of one table from an mdb, so I have to transpose the fields like you see to accomadate a table in the Word doc.
The real trick is that this has to be used by people after I leave, so it can't be real complicated. I have the data entry for the mdb going into normalized tables, and then this query needs to pull that data into the transposed table above. That way, I have all the associated data for one "Name" in one record. I tried to use crosstabs first (I don't suppose you tried that did you? :cool: ), and then ended up with the query above.
I think I can get the code you gave me to work, the trick is the max services as you indicated, I need to pull that value into the code, and I can't how to do that right off the top of my head, but I might get it, or not.
One nice thing about this is that I'm building it from scratch, so I can set it up however I want; there's no exisiting data I have to work into it.

Sheesh.

Thanks for reading this far!

-Corticus
 
Upvote 0
Hullo. I'm like as not WAY off base with my thoughts here, but, would a Cross-Tab Query work for you? Set the Name, ServiceName and Rate as Rows, and ServiceID as Columns?

Shot in the dark, but, HTH (y)

P
 
Upvote 0
Thanks Philem,

Tried the crosstab thing, problem is, you need multiple column headers, and there not supposed to sum or perform any group calculations.

I came up with something that should work.

What I did was, create a Cartesian query between the Services table and the Entities table, thus creating a list of every possible entity and service combination, then I link a bunch of instances of the Rate table (this is where the rate for a service is kept, joined to the Service table on service ID), each joined on entity, with the first instance of the Rate table having the service criteria set to one, the next instance has the service criteria set to two, and so on. You just have to make sure there is an serviceID associated with each instance of the rate table, even is the services name is blank.

Here's my elegant SQL,
SELECT TblEntities.EntityID, TblEntities.County, QryRates.ServiceName AS Serv1, QryRates.BillableRate AS Rate1, QryRates.Units AS Units1, QryRates_1.ServiceName AS Serv2, QryRates_1.BillableRate AS Rate2, QryRates_1.Units AS Units2, QryRates_2.ServiceName AS Serv3, QryRates_2.BillableRate AS Rate3, QryRates_2.Units AS Units3, QryRates_3.ServiceName AS Serv4, QryRates_3.BillableRate AS Rate4, QryRates_3.Units AS Units4, QryRates_4.ServiceName AS Serv5, QryRates_4.BillableRate AS Rate5, QryRates_4.Units AS Units5
FROM QryRates AS QryRates_4 RIGHT JOIN (QryRates AS QryRates_3 RIGHT JOIN (((TblEntities LEFT JOIN QryRates ON TblEntities.EntityID = QryRates.EntityID) LEFT JOIN QryRates AS QryRates_1 ON TblEntities.EntityID = QryRates_1.EntityID) LEFT JOIN QryRates AS QryRates_2 ON TblEntities.EntityID = QryRates_2.EntityID) ON QryRates_3.EntityID = TblEntities.EntityID) ON QryRates_4.EntityID = TblEntities.EntityID
WHERE (((QryRates.ServiceID)=1) AND ((QryRates_1.ServiceID)=2) AND ((QryRates_2.ServiceID)=3) AND ((QryRates_3.ServiceID)=4) AND ((QryRates_4.ServiceID)=5));

Nice eh? ;)

Thanks for the help, I'd still love to hear a suggestion for something that will work better, but I can't imagine anyone would want to read all this!

-Corticus
 
Upvote 0
Glad to hear you got something working. Another option would be to do a Pivot Table in Excel. That's normally what I do when things start to get too weird for Access. :eek:

P
 
Upvote 0
Heehee,

That's funny you should mention that. This project was in Excel, but we had a host of Excel related problems as well. But as far as organizing the data and presenting in the manner I wanted, Excel did great, it just doesn't offer me the relational tools Access does, which I need.

Thanks for the help,
-Corticus
 
Upvote 0

Forum statistics

Threads
1,221,531
Messages
6,160,375
Members
451,642
Latest member
mirofa

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top