我目前正在编写一个Delphi应用程序,它使用ADO在DB2数据库上运行查询。
其中一个要求是用户应该能够使用日期定义查询,例如“显示过去60天内的所有数据”或“向我显示2009年11月20日至2010年1月18日之间的所有数据”。这不是问题,除了两个事实:
我需要知道的是,是否有一种有效的算法来构造从数据库中提取指定信息所需的SQL。例如,今天是1月18日,所以要从11月20日到今天提取所有信息,我需要一个类似这样的SQL语句:
SELECT data WHERE
((day >= 20) AND (month = 11) AND (year = 2009)) OR
((month = 12) AND (year = 2009)) OR
((day <= 18) AND (month = 1) AND (year = 2010))
显然,这是一个微不足道且相对简单的示例,但如果用户想要从2008年11月而不是2009年检索数据,则查询会变得更大。
这是我构建SQL语句的唯一方法,还是有更有效的方法来执行此操作?
答案 0 :(得分:6)
在DB2中,以下内容应将您的单独列转换为日期类型: 日期(年||月||日)
如果您有两个日期,则可以使用减法来接收两者之间的天数,因此您的where子句可以包括
日期(年||月||日)&gt; CURRENT_DATE - 60
答案 1 :(得分:1)
您可以将其构建为将年/月/日转换为日期数据类型,但这会妨碍索引的使用,因此性能可能会成为问题。
db2是否已经计算了可以编制索引的列,您是否可以添加该列?或者可能是一个可以有索引/持久计算列的视图?
如果您有年/月/日的索引,那么您拥有的代码可能最适合提高性能。
答案 2 :(得分:1)
Galghamon SQL Date Interval Algorithm提供的答案在代码方面效率很高,但无法利用索引。
我建议你在Delphi中执行所有必要的计算,这样你的逻辑可以在概念上简化为以下之一:
(DateCol > @DateVal)
(DateCol >= @DateVal)
(DateCol < @DateVal)
(DateCol <= @DateVal)
(DateCol = @DateVal)
然后可以针对您的相当不幸的架构进行扩展,如下所示(使用前2个示例):
(YearCol > @YearVal OR (YearCol = @YearVal AND MonthCol > @MonthVal) OR (YearCol = @YearVal AND MonthCol = @MonthVal AND DayCol > @DayVal))
(YearCol > @YearVal OR (YearCol = @YearVal AND MonthCol > @MonthVal) OR (YearCol = @YearVal AND MonthCol = @MonthVal AND DayCol >= @DayVal))
注意:您需要准确了解包含的位置以及使用排他性不等式运算符的位置。
答案 3 :(得分:0)
在MSSQL中,我会尝试编写一个函数来返回自数据日期以来的天数。在Firebird中,我会使用Delphi用户定义的函数或至少一个可选的存储过程执行相同的操作。我不知道是否可以使用这两个选项中的任何一个扩展DB2 SQL,但是如果你可以将逻辑包装在类似的东西中,它将使你的工作更容易。我在页面右侧的相关帖子中看到了DB2 SQL UDF的提及。我希望这有用。
答案 4 :(得分:0)
因为您要与日期进行比较,所以您应该首先将非日期值转换为日期。这使您可以比较日期和日期,从那里很容易
答案 5 :(得分:0)
关于您对数据库更改的评论。考虑为日期添加单个列。只有当日期,月份和年份中的至少一个列更新时,此列才会由触发器写入。然后,您可以自由地索引此列并使用它。
您不会影响任何现有软件,并且您可以方便地使用日期列。请记住,您今天编写的代码需要在6个月内由其他开发人员阅读。
因此,如果您仍然无法进行数据库更改,请考虑Galghamon的解决方案,因为它易于理解(维护成本低)。只有性能影响迫使你去做,才能使用Craig Young的解决方案。