我已经接管了医疗诊所的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]);
答案 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
查询中所示。您需要添加一个附加条件来抑制与正确日期范围不匹配的行(因为另一个约会确实如此)。