Query Challange

GregD

Registered User.
Local time
Yesterday, 23:26
Joined
Oct 12, 2007
Messages
47
This is not homework, I actually do this for a living, but I'm having brain freeze on this one and I'm swamped with work right now. The code below will create a table with sample data.

The data is for a group of patients. There is a table that has dozens of lab tests for the patients. Dozens of tests covering dozens of dates. Each patient can have more than one of the same test on a given date and multiple of the same tests through out the year.

Normally, finding the last date or the highest value for a specific test across a sub-set of patients is not an issue. In the case of a particular pair of tests I must consider them to be the same test and I may be called on to find the last one or the one with the highest or lowest value in a date range.

I wrote code to do this, but it runs slow. I want to come up with away to do this only with queries so I can speed up the process by taking advantage of the Jet engine.

The two tests are LDL and LDL (Direct). All of the tests dates in the table will be for 2007. I need to find the last test of either test - but only one - for each patient. In some cases there are multiple of each on the same date, and in that case I need the test with the lowest value. The multiples on the same date could be the same test or they could be one or more of each test with different values.

Anyone?




Code:
Public Sub LabTest()
    Dim k As Integer
    Dim i As Integer
    Dim sChartNumber As String
    Dim sTestName As String
    Dim iValue As Integer
    Dim dTestDate As Date
    Dim dTestDateOld As Date
    
    DoCmd.RunSQL "SELECT '96523' AS ChartNumber, #1/1/2008# AS LabDate, 65 AS LabValue, 'LDL' AS ItemName INTO tblLabTest"

    Randomize
    
    With CurrentDb.OpenRecordset("tblLabTest", dbOpenDynaset)
        For k = 1 To 50
            sChartNumber = Trim(Str(CInt((32000 * Rnd) + 1)))
            For i = 1 To 8
                Select Case i
                    Case 1
                        sTestName = "AST"
                    Case 2
                        sTestName = "MicroAl"
                    Case 3
                        sTestName = "HemoglbinA1c"
                    Case 4
                        sTestName = "Potasium"
                    Case Else
                        If CInt((32000 * Rnd) + 1) Mod 2 = 0 Then
                            sTestName = "LDL"
                        Else
                            sTestName = "LDL (Direct)"
                        End If
                End Select
                iValue = CInt((150 * Rnd) + 1)
                
                dTestDateOld = dTestDate
                
                dTestDate = DateSerial(2007, CInt((12 * Rnd) + 1), CInt((28 * Rnd) + 1))
                If k > 25 And k < 30 Then
                    If i Mod 2 = 0 Then
                        Debug.Print sChartNumber
                        dTestDate = dTestDateOld
                    End If
                End If
                
                .AddNew
                !ChartNumber = sChartNumber
                !LabDate = dTestDate
                !LabValue = iValue
                !ItemName = sTestName
                .Update
                
            Next
        Next
    
        .Close
    End With
    
End Sub
 
I assume tblLabTests has a unique record identifier, I will assume so with the assumption that it is a single fields and comprizes the PrimaryKey.

Code:
SELECT ChartNumber, LabDate, Labvalue, LabName
FROM tblLabTests
WHERE LabTestID = (SELECT Top 1 LabTestID
                   FROM tblLastTests As vTbl
                   WHERE vTbl.ChartNumber = tblLabTests.ChartNumber
                         AND vTbl.ItemName In ('LDL','LDL (Direct)') 
                   ORDER BY LabDate DESC, LabValue ASC, LabTestID)

... Probably not goin to win any speed awards though!! ... but probably faster than a UDF.
 
You can assume no such thing. The queries I must run are based on tables exported from someone else's SQL Server views.

However, your query is intriguing. I'll run some tests when I have a chance to come up for air. This may be a good start, but I'm not sure it address multiple - yet different - labs on the same date.
 
>> You can assume no such thing <<

... I am unsure how to read your tone here? ... are you saying that the assumptions I made are not the case, or are you put off by my assumptions ...

If the assumptions I made are not in place, can you reveal some more about the structures you are dealing with?
 
Last edited:
>> You can assume no such thing <<

... I am unsure how to read your tone here? ... are you saying that the assumptions I made are not the case, or are you put off by my assumptions ...

If the assumptions I made are not in place, can you reveal some more about the structures you are dealing with?

Yikes! No tone of any kind was implied other than maybe a little weariness on my part. I meant it just as I wrote it. You were assuming that there was a primary key on the table and only meant to indicate that there was not. No offense was implied.
 
Cool! ... Thanks for the reply and clarification! ... The more and more I read it, the more I figured it was as you stated ... :D

...

Did my suggestion help? ... is there ANY field in the table (view) that can be deemed as unique to the row/record? ... like timestamp of the entry? Having a unique row identifier makes it a whole lot easier! ...
 
Actually, I can't get your query to run at all. I corrected the misspelled table name and it still wouldn't run. Did you run this against the test data?
 
Nope ... completely AIR CODE my friend ... foot loose and fancy free!!! ... can you attach a sample chunk of data, or indicate how to construct a sample set of data? ... also, just for verification, can you post your SQL statment that you used?
 
In the first message there is a chunk of code that builds a table of sample data.
 
Can I divert slightly and ask why there isn't a PK on your table?
Do you have no control at all over the schema in this case?
 
You know, I didn't design the database, table, or the view the table is exported from. I'm sure the underlying table has a primary key but that is not what I'm given to work with. The data I have is exported as a CSV file from SQL server view. The best I could do would be to add an auto number field but that wouldn't really help me achieve what I want. I still need to work with the two different labs as if they were one.
 
>> The best I could do would be to add an auto number field but that wouldn't really help me achieve what I want. I still need to work with the two different labs as if they were one. <<

If you are importing the CSV to an Access table, then I would highly recommend you ADD and AutoNumber field and set it as the PK ... You can dump both labs' info into the same table and treat it as one.
 
It sounds simple enough, doesn't it. What if you have two labs in the same day. You need to lowest lab value, and you need to know what type it is.
 
>> What if you have two labs in the same day. You need to lowest lab value, and you need to know what type it is. <<

That is what my query that I posted does (most recent, lowest value lab)! {ORDER BY LabDate DESC, LabValue ASC, LabTestID) .. but I need to unique record identifer (LabTestID - Autonumber, PrimaryKey) to get the values to display from the appropriate record ....

------

Maybe you can post the CSV (if you want, a CSV from each different lab!) and I will provide a sample db ...
 
I'm not sure how your query will return the desired results in all cases if I don't know that the two labs in one day are the same or not. This happens in a small number of situations but that is really the crux of the problem. Getting something to work 90% of the time was never an issue. What I have now works 100% of the time, but it slow.

Having said that, this discussion has given me some ideas on how I can achieve it....I think. Anyway, I'm going to revisit this next week and I'll let you know how it turns out.

Thanks everyone for your input .
 
>> I don't know that the two labs in one day are the same or not. <<

If the data is the rows is the same, then it does not matter which row is brought up for visulization. The query I designed will bring the one with the lowest AutoID "up", and the other would be lost due to the criteria not being matched.

... Can you not just post a CSV? ... or how 'bout a few rows of data (preferable with the concern you express, and then the rows of what the final result should be?
 
Due to federal regulations, and the fact that I would be fired on the spot, I'm not allowed to post patient's medical information on the web, or any where, for that matter. That was the reason I posted to the code in the first message that will build a table of sample data.
 
>> I'm not allowed to post patient's medical information on the web <<
Could you not mask it? ... make it so its untracible to a person? ... I understand your caution though ... so ...

... can you give me the structure of the CSV along with the data types for each column (from all the different labs you want to treat as one) as well as the Table structure of the resultant table? ... I will build my own sample data ... then we can make sure I am understanding your specification correctly ... plus the data will be fake ... and you get to keep your job ..... YEAH!!! ....
 
You've got it in the first message. Paste that code in a module window and press F5. It will create the table for you.
 
.... Ahhhh .... it all coming together now ... Just hold out this board while I smack my head against it! .... :eek: .... For the life of me I could not see where the code you posted was accomplishing the task at hand!!! ... but finally you turned on the switch in my brain that said ... HEY you doof, the code creates a sample table for you!!! .... DOH!!! ....

.... Okay ....

With this snapshot of data ... (notice the addition of the LabTestID field ... an Autonumber, set as the PK)
This SQL which extracts ONLY the latest between LDL and LDL (Direct)...

{image did not xfer}

Code:
SELECT ChartNumber, LabDate, Labvalue, ItemName
FROM tblLabTest
WHERE LabTestID = (SELECT Top 1 LabTestID
                   FROM tblLabTest As vTbl
                   WHERE vTbl.ChartNumber = tblLabTest.ChartNumber
                         AND vTbl.ItemName In ('LDL','LDL (Direct)') 
                   ORDER BY LabDate DESC, LabValue ASC, LabTestID)

Will return this snapshot of data ...

{image did not xfer}

To get the latest of EACH test, whilst counting LDL and LDL (Direct) as the same item (or test) then this SQL ...

Code:
SELECT ChartNumber, LabDate, Labvalue, ItemName
FROM tblLabTest
WHERE LabTestID = (SELECT Top 1 LabTestID
     FROM tblLabTest As vTbl
     WHERE vTbl.ChartNumber = tblLabTest.ChartNumber
          AND IIf(Left(vTbl.ItemName,3)='LDL','LDL',vTbl.ItemName) = IIf(Left(tblLabTest.ItemName,3)='LDL','LDL',tblLabTest.ItemName)
     ORDER BY LabDate DESC, LabValue ASC, LabTestID)

Will yeild this data ...

{image did not xfer}

Please note that all data is filtered for one chart for illustration purposes. A sample database is attached for your viewing ...

Hope this helps!!!

EDITS ADDED >>>>
The tables of info trasfered as one HUGE single line string ... so .... just take a look at the db ... there are two queries ... one to show the latest of either LDL and LDL (Direct), and one to show the latest of ANY test with LDL and LDL Direct being treated as the same, but the results show which one was counted as the lastest. Note that the first SQL is similar to the SQL I originally posted ... except my original had some typos ... that AIR CODE can get you everytime!!!
 

Attachments

Last edited:

Users who are viewing this thread

Back
Top Bottom