开发者

MS Access Select Query fields based on date range given

开发者 https://www.devze.com 2023-03-15 02:19 出处:网络
I have taken over management of an Access 2003 database for a medical clinic.Unfortunately, the person who created the DB didn\'t know much about databases and threw everything into one HUGE table.So

I have taken over management of an Access 2003 database for a medical clinic. Unfortunately, the person who created the DB didn't know much about databases and threw everything into one HUGE table. So right now I have a table called All Clinic Data with the following fields (and about 40 others): PatientID, First Name, Last Name, Appt Date, OB at Appt, Billing Item #1, Second Appt Date, Reason for Second Appt, OB at Second Appt, Billing Item #2.

I know that this is not the optimal way to arrange the data and a complete overhaul of the DB is planned in the future. However, right now I need to create reports containing only the information for the appointments that occured in a certain date range.

This is the SQL query I am currently using to populate my report but it captures all the appointments for a patient from the table if one of them is in the date range given.

SELECT 
    Format([Input start date],"mm/dd/yy") & " through " & Format([Input end date],"mm/dd/yy") AS Expr1, 
    [All Clinic Data].[PatientID], [All Clinic Data].[Last Name], 
    [All Clinic Data].[First Name], [All Clinic Data].[Appt Date], 
    [All Clinic Data].[OB at Appt], [All Clinic Data].[Billing Item #1], 
    [All Clinic Data].[Second Appt Date], [All Clinic Data].[Reason for Second Appt], 
    [All Clinic Data].[OB at Second Appt], [All Clinic Data].[Billing Item #2] 
FROM [All Clinic Data]
WHERE (
        (([All Clinic Data].[Appt Date])>[Input start date] And 
        ([All Clinic Data].[Appt Date])<[Input end date])
    ) 
开发者_运维问答    OR 
    (
        (([All Clinic Data].[Second Appt Date])>[Input start date] And 
        ([All Clinic Data].[Second Appt Date])<[Input end date])
    ) 
ORDER BY [All Clinic Data].[Last Name];

Note Input start date & Input end date are parameters entered when the query runs. I have tried using the IIF to remove the excess data but I don't know how to structure the statement so that it shows only the appointment dates and associated data (OB and Billing Item) within the given date range.

Example:

1, Sally, Jones, 1/04/2010, Dr.A, 2/05/2011, Dr. B, Flu

2, Jennifer, Baker, 7/05/2010, Dr.X, 15/05/2011, Dr. B, Checkup

3, Joe, Smith, 20/06/2010, Dr.S, 

4, Tina, Turner, 17/05/2010, Dr.X, 15/06/2011, Dr. B, Checkup 

If [Input start date] = May 1, 2010 and [Input end date] = May 31, 2010

I'd like my report to contain:

Sally, Jones, 

 1. 2/05/2011, Dr. B, Flu

Jennifer, Baker, 

 1. 7/05/2010, Dr.X  
 2. 15/05/2011, Dr.B, Checkup

Tina, Turner, 

 1. 17/05/2010, Dr.X

I hope this is enough information. Thank you for your help.

UPDATE 1 Here's my first step towards trying what Mike suggested below. I'm using phn as the identifier for the patient info that I'll grab later. I'm getting an compiliation error and I'm not sophisticated enough to know what I've done wrong. Any ideas?

SELECT 
    Format([Input start date],"mm/dd/yy") & " through " & Format([Input end     date],"mm/dd/yy") AS Expr1, 
    [All Clinic Data].PHN AS Phn, [All Clinic Data].[Appt Date] AS Date, 
    [All Clinic Data].[OB at Appt] AS OBName, 
    [All Clinic Data].[Billing Item #1] AS Billing 
FROM [All Clinic Data]

WHERE ([All Clinic Data].[Appt Date]>[Input start date] And [All Clinic Data].[Appt Date]<[Input end date])

UNION

SELECT 
    Format([Input start date],"mm/dd/yy") & " through " & Format([Input end date],"mm/dd/yy") AS Expr1, 
    [All Clinic Data].PHN AS Phn, [All Clinic Data].[Second Appt Date] AS Date, 
    [All Clinic Data].[OB at Second App] AS OBName, 
    [All Clinic Data].[Billing Item #2] AS Billing FROM [All Clinic Data]

WHERE ([All Clinic Data].[Second Appt Date]>[Input start date] And [All Clinic Data].[Second Appt Date]<[Input end date]);


Create a query called PatientAppointment:

SELECT
   D.PatientID,
   D.[Appt Date] AS ApptDate,
   D.[OB at Appt] AS OBName
   D.[Billing Item #1] AS Billing 
UNION ALL SELECT
   D.PatientID,
   D.[Second Appt Date],
   D.[OB at Second Appt],
   D.[Billing Item #2];

Please note that this query can't be edited in the designer. You can only work with it in SQL view. Then, use this query as your source for all queries on this data:

SELECT *
FROM
   PatientAppointment PA
WHERE
    PA.ApptDate >= [Input start date]
    AND PA.ApptDate < [Input end date];

I don't know how the performance will be, but you can try it and let us know. Basically, treat this as your appointment table and don't even deal with these columns in the main table. This would be a way for you to slowly start changing the application, even, because eventually you could make this the actual table and migrate the data.

Here's a possible alternate solution that could, let me stress could be better. Or worse:

Create a table with one column and row in it. It doesn't matter what the name of the table or row is but make the data type numeric Long. I'm going to assume you named this table Dual. Then make the same PatientAppointment query:

SELECT
    D.PatientID,
    Iif(A.ApptNum = 1, D.[Appt Date], D.[Second Appt Date]) ApptDate,
    Iif(A.ApptNum = 1, D.[OB at Appt], D.[OB at Second Appt]) OBName,
    Iif(A.ApptNum = 1, D.[Billing Item #1], D.[Billing Item #2]) Billing
FROM
   [All Clinic Data] D
   INNER JOIN [
      SELECT 1 AS ApptNum FROM Dual
      UNION ALL SELECT 2 FROM Dual
   ]. A ON 1 = 1

If you have "SQL 92 Syntax" turned on in your database, let me know and I'll switch to the better syntax in this final query.

You also can do the UNION ALL SELECT method as suggested to you in comments (I recommend against just UNION SELECT because this makes the engine do more work to eliminate duplicates). I can't immediately see anything wrong with your query, try each separate SELECT statement by itself to see if one has problems.

Finally, if your performance with any of these methods is too awful, then a hybrid of my Dual query with your given query could do the trick. Do your query as you showed with a big OR condition, but split the two appointments out to separate rows as in the Dual query above. You will want to put an additional condition to suppress rows that don't match the correct date range (because the other appointment did).

0

精彩评论

暂无评论...
验证码 换一张
取 消