假设我在Sql Server 2008中具有下表:
ItemId StartDate EndDate
1 NULL 2011-01-15
2 2011-01-16 2011-01-25
3 2011-01-26 NULL
如您所见,该表具有StartDate和EndDate列。我想验证这些列中的数据。间隔不能相互冲突。因此,上面的表是有效的,但是下一个表是无效的,因为第一行的结束日期大于第二行的StartDate。
ItemId StartDate EndDate
1 NULL 2011-01-17
2 2011-01-16 2011-01-25
3 2011-01-26 NULL
NULL
在这里表示无穷大。
您能帮我写一个脚本进行数据验证吗?
[第二项任务]
感谢您的回答。我很复杂。假设我有这样的表:
ItemId IntervalId StartDate EndDate 1 1 NULL 2011-01-15 2 1 2011-01-16 2011-01-25 3 1 2011-01-26 NULL 4 2 NULL 2011-01-17 5 2 2011-01-16 2011-01-25 6 2 2011-01-26 NULL
在这里,我想验证一组中的间隔IntervalId
,但不验证整个表中的间隔。因此,间隔1将是有效的,但是间隔2将是无效的。
并且。可以在表中添加约束以避免此类无效记录吗?
[最终解决方案]
我创建了一个函数来检查间隔是否冲突:
CREATE FUNCTION [dbo].[fnIntervalConflict]
(
@intervalId INT,
@originalItemId INT,
@startDate DATETIME,
@endDate DATETIME
)
RETURNS BIT
AS
BEGIN
SET @startDate = ISNULL(@startDate,'1/1/1753 12:00:00 AM')
SET @endDate = ISNULL(@endDate,'12/31/9999 11:59:59 PM')
DECLARE @conflict BIT = 0
SELECT TOP 1 @conflict = 1
FROM Items
WHERE IntervalId = @intervalId
AND ItemId <> @originalItemId
AND (
(ISNULL(StartDate,'1/1/1753 12:00:00 AM') >= @startDate
AND ISNULL(StartDate,'1/1/1753 12:00:00 AM') <= @endDate)
OR (ISNULL(EndDate,'12/31/9999 11:59:59 PM') >= @startDate
AND ISNULL(EndDate,'12/31/9999 11:59:59 PM') <= @endDate)
)
RETURN @conflict
END
然后我在表中添加了2个约束:
ALTER TABLE dbo.Items ADD CONSTRAINT
CK_Items_Dates CHECK (StartDate IS NULL OR EndDate IS NULL OR StartDate <= EndDate)
GO
和
ALTER TABLE dbo.Items ADD CONSTRAINT
CK_Items_ValidInterval CHECK (([dbo].[fnIntervalConflict]([IntervalId], ItemId,[StartDate],[EndDate])=(0)))
GO
我知道,第二个约束减慢了插入和更新操作的速度,但这对我的应用程序不是很重要。而且,现在我可以fnIntervalConflict
在插入和更新表中的数据之前从应用程序代码中调用函数。
declare @T table (ItemId int, IntervalID int, StartDate datetime, EndDate datetime)
insert into @T
select 1, 1, NULL, '2011-01-15' union all
select 2, 1, '2011-01-16', '2011-01-25' union all
select 3, 1, '2011-01-26', NULL union all
select 4, 2, NULL, '2011-01-17' union all
select 5, 2, '2011-01-16', '2011-01-25' union all
select 6, 2, '2011-01-26', NULL
select T1.*
from @T as T1
inner join @T as T2
on coalesce(T1.StartDate, '1753-01-01') < coalesce(T2.EndDate, '9999-12-31') and
coalesce(T1.EndDate, '9999-12-31') > coalesce(T2.StartDate, '1753-01-01') and
T1.IntervalID = T2.IntervalID and
T1.ItemId <> T2.ItemId
结果:
ItemId IntervalID StartDate EndDate
----------- ----------- ----------------------- -----------------------
5 2 2011-01-16 00:00:00.000 2011-01-25 00:00:00.000
4 2 NULL 2011-01-17 00:00:00.000
问题内容: 我正在管理事件数据库。每个事件都有开始和结束时间戳记()。 目前,我可以通过一个SQL查询执行以下操作: 建立日历,并记下发生事件的日期 列出给定日期(YYYY / MM / DD,YYYY / MM)中发生的事件 问题是当一个事件跨越几天时,我无法在它的开始和结束时间戳之间的日期列出它。 例如: 活动开始于2011/05/25和结束于2011/05/27,但我无法在页面2011/05
问题内容: 我有一个包含2个字段的表:唯一ID,用户ID(外键)和日期时间。这是对服务的访问日志。我在SQL Server中工作,但我希望得到不可知论的答案。 我想使用SQL为最长间隔开始的特定用户查找ID。 因此,举例来说,假设我的值如下(为一位用户简化): 如果我搜索用户1的最长间隔,我将得到ID 2(也可以在那儿获得间隔的长度,但不那么关键)。 在SQL中最有效的方法是什么? 注意:ID不一
问题内容: 首先,感谢任何帮助我解决此问题的人。我正在使用SQL 2005,但如果05中没有可用的解决方案,则可以使用2008。 我有一排数据看起来像这样: 因此,我要做的是每天计算每个区域的总请求量。结果应为: 我该怎么做呢?我很沮丧,没有任何谷歌搜索帮助。 问题答案: 您将需要一个Calendar表,或者可以使用CTE生成一个。一旦有了这些,其余的查询就应该变得无关紧要了。由于递归问题并且不允
问题内容: 我有一列的数据像 我需要编写一个SQL查询/过程,这将有助于我获取日期之间差异的平均值。对于上面的示例,它将是 (19 + 8 + 10)/3=12.33。 请提供帮助。 在此先感谢Geetha 问题答案: 我不知道您的RDBMS,但这是来自SQL Server。另外,您的计算之一是错误的-02/09/2011-13/08/2011是20,而不是19。 产生的结果是12.667:(20
问题内容: 我有一张可以容纳一年中所有天/月的表 例如 我有一张表格,显示来自不同数据集的日期范围 例如 我如何比较这两个表以显示该特定月份的数据集中缺少哪些日期 对于上面示例中的数据集所在的示例,EG缺少日期范围01/09/2013-19/09/2013 谢谢你的帮助! 问题答案: 您可以使用CTE并通过以下方式编写查询:
问题内容: 当我尝试执行此代码时,在“ with DateDimension”行出现错误: 消息206,级别16,状态2,第15行 操作数类型冲突:日期与int不兼容 这是我正在使用的SQL查询: 问题答案: 您的问题在于该部分。尝试使用,如下所示: 编辑:我不知道您的原始代码是否要使用该选项,但是如果您不知道我建议您阅读此内容。基本上,在这种情况下,这意味着您可以使用CTE列出1,000个日期。