MS Access根据给定的日期范围选择查询字段

时间:2011-06-24 21:40:44

标签: sql ms-access ms-access-2003

我已经接管了医疗诊所的Access 2003数据库管理。不幸的是,创建数据库的人对数据库知之甚少,并将所有内容都放在一个巨大的表中。所以现在我有一个名为All Clinic Data的表,其中包含以下字段(以及大约40个其他字段):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.

我知道这不是排列数据的最佳方式,未来计划对数据库进行全面检修。但是,现在我需要创建仅包含特定日期范围内约会信息的报告。

这是我目前用于填充报告的SQL查询,但如果其中一个患者处于给定的日期范围内,它会从表中捕获患者的所有约会。

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];

注意输入开始日期&amp;输入结束日期是查询运行时输入的参数。 我已经尝试使用IIF来删除多余的数据,但我不知道如何构造语句,以便它只显示给定日期范围内的约会日期和相关数据(OB和Billing Item)。

示例:

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 

如果[输入开始日期] = 2010年5月1日,[输入结束日期] = 2010年5月31日

我希望我的报告包含:

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

我希望这是足够的信息。谢谢你的帮助。

更新1 这是我尝试下面迈克建议的第一步。我正在使用phn作为患者信息的标识符,我将在稍后获取。我得到了一个编译错误,我不够老练,不知道我做错了什么。有什么想法吗?

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]);

1 个答案:

答案 0 :(得分:1)

创建名为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];

请注意,无法在设计器中编辑此查询。您只能在SQL视图中使用它。然后,使用此查询作为此数据的所有查询的来源:

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

我不知道表现如何,但你可以尝试一下,让我们知道。基本上,将其视为您的约会表,甚至不在主表中处理这些列。这将是您慢慢开始更改应用程序的一种方法,因为最终您可以将其设置为实际表并迁移数据。

这是可能的替代解决方案,让我强调可以更好。或者更糟:

创建一个包含一列和一行的表。表或行的名称是什么并不重要,但使数据类型为数字Long。我假设你把这个表命名为Dual。然后进行相同的PatientAppointment查询:

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

如果您在数据库中打开了“SQL 92语法”,请告诉我,我将在此最终查询中切换到更好的语法。

您也可以按照建议的方式执行UNION ALL SELECT方法(我建议仅针对UNION SELECT,因为这会让引擎做更多工作来消除重复项)。我不能立即看到你的查询有任何问题,单独尝试每个单独的SELECT语句,看看是否有问题。

最后,如果您使用这些方法的表现太糟糕,那么我的Dual查询与您给定查询的混合可以解决问题。如您所示,使用大OR条件进行查询,但将两个约会拆分为单独的行,如上面的Dual查询中所示。您需要添加一个附加条件来抑制与正确日期范围不匹配的行(因为另一个约会确实如此)。