我正在构建一个SSIS包,我需要从前一天下午4:15:01到今天下午4:15:00获取数据,但到目前为止我知道的唯一查询是如何得到前一天。我不知道如何在同一个查询中添加小时,分钟和秒。有人可以告诉我如何在这个SQL查询中添加小时,分钟和秒吗? 以下是我到目前为止的查询。
SELECT Posted_Date, Total_Payment FROM
Table1
WHERE Posted_Date >= dateadd(day, datediff(day, 1, Getdate()), 0)
and Posted_date < dateadd(day, datediff(day, 0, getdate()), 0)
order by posted_date
答案 0 :(得分:8)
在这里要非常小心精确度 - 说昨天下午4:15:01你想要的东西,意味着在某些时候你可能会丢失数据(例如下午4:15:00.500)。使用开放式范围要好得多,我通常喜欢在查询之外计算边界:
DECLARE @today DATETIME, @today_at_1615 DATETIME;
SELECT @today = DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0),
@today_at_1615 = DATEADD(MINUTE, 16.25*60, @today);
SELECT Posted_Date, Total_Payment
FROM dbo.Table1
WHERE Posted_Date > DATEADD(DAY, -1, @today_at_1615)
AND Posted_Date <= @today_at_1615
ORDER BY Posted_date;
您还应避免在此类查询中使用DATEDIFF
- a cardinality estimation bug可以really affect the performance of your query。我不相信这个bug会影响SQL Server 2005,但是如果你想要超级安全,你可以把它改成稍微贵一些:
SELECT @today = CONVERT(CHAR(8), GETDATE(), 112),
在任何一种情况下,您都应该使用某种标记来标记此代码,这样当您进入SQL Server 2008或更高版本时,您可以更新它以使用更加优化:
SELECT @today = CONVERT(DATE, GETDATE()),
我创建了一个带有Execute SQL Task
的SSIS包,用于创建我的表并用数据填充它,然后由Data Flow Task
我创建了一个执行SQL任务,连接到OLE DB连接管理器并使用以下直接输入。
-- This script sets up a table for consumption by the DFT
IF EXISTS
(
SELECT * FROM sys.tables AS T WHERE T.name = 'Table1' AND T.schema_id = SCHEMA_ID('dbo')
)
BEGIN
DROP TABLE dbo.Table1;
END;
CREATE table dbo.Table1
(
Posted_Date datetime NOT NULL
, Total_Payment int NOT NULL
);
INSERT INTO
dbo.Table1
(
Posted_Date
, Total_Payment
)
SELECT
DATEADD(minute, D.rn, DATEADD(d, -1, CURRENT_TIMESTAMP)) AS Posted_Date
, D.rn
FROM
(
-- 2 days worth of data
SELECT TOP (60*24*2)
DI.rn
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS rn
FROM sys.all_columns AS AC
) DI
) D;
右键单击Execute SQL Task并执行它。这样可以确保创建表,以便我们可以在下一步中使用它。
我创建了一个Data Flow Task
并将DelayValidation
属性设置为True,因为我的连接管理器指向tempdb。在现实世界中可能不需要这样做。
我添加了一个OLE DB Source组件并将其配置为使用第一个查询
然后我添加了一个派生列,允许我将数据查看器附加到流程并关闭该程序包。您可以观察到流过的最后一个值是否符合预期。
答案 1 :(得分:0)
我认为这会有类似的作用。
DECLARE @today DATETIME, @today_at_1615 DATETIME;
SELECT @today = CONVERT(DATE, GETDATE()),
@today_at_1615 = DATEADD(MINUTE, 16.25*60, @today);
SELECT Posted_Date, Total_Payment
FROM dbo.Table1
WHERE Posted_Date between DATEADD(DAY, -1, @today_at_1615) AND @today_at_1615
ORDER BY Posted_date
对于使用BETWEEN会发表评论,但我没有代表它。是否有理由不使用between子句?
答案 2 :(得分:-6)
提出同一问题的另一种方式:向我显示今天发布的数据,如果它在7小时,44分钟和59秒后发布。
SELECT Posted_Date, Total_Payment FROM
Table1
WHERE CAST(DATEADD(second,7*60*60+44*60+59,Posted_Date) AS date) = CAST(GETDATE() as date)
这将平稳处理fencepost问题,小数秒和夏令时,并且CAST(DATEADD(second,7*60*60+44*60+59,Posted_Date) AS date)