【问题标题】:Starting result set at certain point in results在结果中的某个点开始结果集
【发布时间】:2014-09-01 19:19:17
【问题描述】:

我遇到了一个问题。基本上,我有一个有 4 列的表,其中一列是日期,返回的结果取决于一天中的时间。如果时间在下午 6 点之前,则按原样返回数据,但如果在 6 点之后,则查找下一个可用日期。

这是一些假设今天是 2014-07-10 的示例数据:

+----------+---------------------+-----------------+----------------+
| Workzone |    ScheduleDate     | NextDayDelivery | StdDayDelivery |
+----------+---------------------+-----------------+----------------+
| SWANS    | 2014-07-11 00:00:00 |               1 |              1 |
| SWANS    | 2014-07-12 00:00:00 |               0 |              1 |
| SWANS    | 2014-07-13 00:00:00 |               0 |              0 |
| SWANS    | 2014-07-14 00:00:00 |               0 |              1 |
| SWANS    | 2014-07-15 00:00:00 |               0 |              1 |
| SWANS    | 2014-07-16 00:00:00 |               0 |              1 |
| SWANS    | 2014-07-17 00:00:00 |               0 |              1 |
| SWANS    | 2014-07-18 00:00:00 |               0 |              1 |
| SWANS    | 2014-07-19 00:00:00 |               0 |              1 |
| SWANS    | 2014-07-20 00:00:00 |               0 |              0 |
+----------+---------------------+-----------------+----------------+

这是目前的查询:

DECLARE @hour AS Int
SET @hour = DatePart(hour, getdate())

SET @hour = 19

-- Work out if the time is before 18:00.  If it is then this is the easy bit, use the data as is.
IF (@hour <= 18)
    BEGIN
        SELECT
            [Workzone]
            ,[ScheduleDate]
            ,[NextDayDelivery]
            ,[StdDayDelivery]
        FROM [tbl_Sys_QuickstartDeliveryQuota]
    END
ELSE
    BEGIN
        -- OTHER QUERY HERE --
    END

所以上面只是检查小时并根据它执行查询。如果在下午 6 点之前,则只需查看表中的数据,否则执行我坚持的其他查询。

上面的示例数据是从第二天开始生成的,所以如果今天是 2014 年 7 月 10 日,那么数据将从 2014 年 7 月 11 日开始。如果第二天是工作日或星期六,则 NextDayDelivery 列将始终以 1 开头,并且所有后续天数都设置为 0;如果是工作日或星期六,则 StdDayDelivery 列将始终以 1 开头;如果是星期日或银行假日,则 StdDayDelivery 列将始终以 0 开头。

如果时间在 6 点之后,我需要做的是调整结果,因为这将改变第二天的交货。

我的想法是使用 StdDayDelivery 列来计算下一个可用的交货日,因此在提供的示例数据中,2014-07-12 将成为 NextDayDelivery 的结果的第一行(如果今天是 11 日)根据设置为 1 的 StdDayDelivery 设置为 1。如果今天的日期是 2014-07-12,那么结果将从 14 日开始,因为 13 日是星期日,所以下一个可用的交货日是 14 日,所以 NextDayDelivery 是14 号 1 号。

我希望这是有道理的。

两个预期的输出是:

如果今天是Friday the 11th,结果将是:

2014-07-12    1    1
2014-07-13    0    0
2014-07-14    0    1
2014-07-15    0    1
2014-07-16    0    1
2014-07-17    0    1
2014-07-18    0    1

如果今天是Sat the 12th,结果将是:

2014-07-13    0    0
2014-07-14    1    1
2014-07-15    0    1
2014-07-16    0    1
2014-07-17    0    1
2014-07-18    0    1

(第 13 个值设置为 0,因为 StdDayDelivery 显示为 0,因为它是星期日)

【问题讨论】:

  • 对不起数据格式,我尝试了很多方法来对齐:(
  • 我很困惑。数据是生成还是存储?特别是NextDayDelivery 列。如果存储,为什么?如果该脚本应该决定将哪一行标记为 1,则此特定列的先前生成似乎没有什么意义。另外,应该显示多少行?脚本中的 SELECT 查询根本没有 WHERE 子句。那么,这是否意味着生成了整个集合?您想如何在下午 6 点之后通过从表中删除它或在相应的 SELECT 语句中使用 WHERE 来省略今天的行?

标签: sql tsql sql-server-2005


【解决方案1】:

看起来CROSS APPLY 可以帮助您完成这项任务。

为 [NextDayDelivery] 计算创建表函数

IF OBJECT_ID(N'dbo.GetData', N'TF') IS NOT NULL
DROP FUNCTION dbo.GetData;
GO
CREATE FUNCTION GetData(@ScheduleDate AS DATETIME, @testDay AS DATETIME) 
RETURNS @VV TABLE
(
    [NextDayDelivery] bit
)
AS 
BEGIN
    INSERT INTO @VV
    SELECT
    CASE 
    WHEN (DATEDIFF(dd, @testDay, @ScheduleDate)=1 AND DATEPART(dw, @ScheduleDate)>1) OR
    (DATEDIFF(dd, @testDay, @ScheduleDate)=2 AND DATEPART(dw, @testDay)=7) THEN 1
    ELSE 0 
    END
    AS [NextDayDelivery] 
    RETURN
END
GO

在 SELECT 中使用这个函数

DECLARE @testDay DATETIME

SET @testDay =  DATEADD(d,1,GETUTCDATE())
-- SET @testDay =  GETUTCDATE()

SELECT t.[ScheduleDate], VV.[NextDayDelivery], t.StdDayDelivery
FROM [tbl_Sys_QuickstartDeliveryQuota] AS t
CROSS APPLY GetData(t.[ScheduleDate], @testDay) AS VV
where t.[ScheduleDate] > @testDay

注意:我的代码假设一周的第一天是星期日。 IE。 SELECT DATEPART(dw, '2014-07-12') 回复我7。如果您使用其他文化,请更正我的代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-12
    • 1970-01-01
    • 2013-10-01
    • 2011-01-08
    • 1970-01-01
    • 2013-05-01
    • 2012-02-08
    相关资源
    最近更新 更多