Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 日期部分固定天数_Sql_Sql Server_Tsql_Datepart - Fatal编程技术网

Sql 日期部分固定天数

Sql 日期部分固定天数,sql,sql-server,tsql,datepart,Sql,Sql Server,Tsql,Datepart,我将datefirst设置为1,但我不知道如何改进它。 我很抱歉提供的信息太少。我正在使用SQL Server。 我上传了.img来举例说明 第%2天为0且POL为“SUUA”时的情况 然后,从CONVERTVARCHAR15,DATEPARTDAY,5+'到'+CONVERTVARCHAR15,DATEPARTDAY,3103 我想展示这样的东西 CASE WHEN DAY % 2 = 0 AND POL = 'SUUA' THEN CONVERT(VARCHAR(15),DATEPART(D

我将datefirst设置为1,但我不知道如何改进它。
我很抱歉提供的信息太少。我正在使用SQL Server。 我上传了.img来举例说明

第%2天为0且POL为“SUUA”时的情况 然后,从CONVERTVARCHAR15,DATEPARTDAY,5+'到'+CONVERTVARCHAR15,DATEPARTDAY,3103

我想展示这样的东西

CASE WHEN DAY % 2 = 0 AND POL = 'SUUA'
THEN CONVERT(VARCHAR(15),DATEPART(DAY,5)) + ' TO ' + CONVERT(VARCHAR(15),DATEPART(DAY,3),103)

我强烈建议为此使用日历表。日历表包含带有附加信息的日期值,因此更容易查找特定日期,如工作日或工作日,如本例所示

以下解决方案使用一个日历表和两个交叉应用运算符来获取以前的收集日期

以下是创建日历表递归CTE的方法:

PORT            COLLECT             DEPARTURE

MANAUS      07/12 TO 12/12     15/12/2018(ODD DAY)
我们将使用它来查找某个特定出发日期之前最近的星期三和星期一。我们使用交叉应用程序将出发日期作为更高的限制,然后搜索特定的工作日1(周一),3(周三)。然后使用带有ORDER BY Date DESC的TOP 1,在出发日期之前获得最高的星期一/星期三

SELECT * FROM #CalendarTable ORDER BY Date DESC

Date        Weekday
2020-01-02  4
2020-01-01  3
2019-12-31  2
2019-12-30  1
2019-12-29  7
2019-12-28  6
2019-12-27  5
2019-12-26  4
2019-12-25  3
2019-12-24  2
2019-12-23  1
2019-12-22  7
2019-12-21  6
2019-12-20  5
2019-12-19  4
2019-12-18  3
2019-12-17  2
2019-12-16  1
2019-12-15  7
2019-12-14  6
2019-12-13  5
2019-12-12  4
2019-12-11  3

这是一个很好的SQL练习。

非常感谢@Ezlo,这太棒了。这是一个很好的SQL练习。我想这会很适合我的工作。很抱歉看起来很无聊,我有一些问题:

编辑:。我注意到VDeparture的日期是固定的。我想和迪纳米克约会。因为当我开始工作的时候

Departure   IsOdd   Collect                     ClosestWednesdayBeforeDeparture     PreviousFridayOfThatWednesday   ClosestMondayBeforeDeparture    PreviousWednesdayOfThatMonday
2018-12-01  1       2018-11-23 TO 2018-11-28    2018-11-28                          2018-11-23                      2018-11-26                      2018-11-21
2018-12-09  1       2018-11-30 TO 2018-12-05    2018-12-05                          2018-11-30                      2018-12-03                      2018-11-28
2018-12-25  1       2018-12-14 TO 2018-12-19    2018-12-19                          2018-12-14                      2018-12-24                      2018-12-19
2018-12-29  1       2018-12-21 TO 2018-12-26    2018-12-26                          2018-12-21                      2018-12-24                      2018-12-19
2019-01-02  0       2018-12-26 TO 2018-12-31    2018-12-26                          2018-12-21                      2018-12-31                      2018-12-26
2019-01-07  1       2018-12-28 TO 2019-01-02    2019-01-02                          2018-12-28                      2018-12-31                      2018-12-26
2019-01-10  0       2019-01-02 TO 2019-01-07    2019-01-09                          2019-01-04                      2019-01-07                      2019-01-02
所有端口的“以固定方式收集”的日期。
对不起,如果我觉得无聊。你们帮了大忙。

请提供示例数据和所需结果。如果没有样本数据,说明就没有多大意义。还可以使用您正在使用的数据库进行标记。您能详细说明一下结果和数据类型吗?同时标记您正在使用的DBMS,我怀疑是SQL Server。您的出发日期应该是周三到周一,这是什么意思?@BRKZ您可以使用“编辑”按钮添加有关您的问题的更多信息。很抱歉,信息太少了。我编辑并添加了一些信息。对不起,我的英语不好。我希望你能理解。@ BRKZ你有什么要求?任何时候你发现自己比简单的日期计算要多得多,你应该考虑日历表。实际上,任何时候你有一个数据库,你都应该添加一个日历表,然后根据需要修改它。日历表和数字表听起来都像是巨大的浪费,但它们可以轻松且显著地提高性能。这应该是任何数据库设计或使用的基本主题。我希望每当有人提出关于SQL的任何问题时,你有没有试过日历表?我的示例中的表V是SampleData,它是我用作示例的硬编码值。只需删除名为SampleData的CTE,并将SampleData中的V替换为包含偏离值的原始表。交叉应用不需要更改,也不需要在交叉应用中再次引用V表,只需通过C.Date-- Build your Collect periods ;WITH SampleData AS ( SELECT V.Departure FROM (VALUES ('2018-12-01'), ('2018-12-09'), ('2018-12-25'), ('2018-12-29'), ('2019-01-02'), ('2019-01-07'), ('2019-01-10')) AS V(Departure) ) SELECT V.Departure, -- Friday to Wednesday ClosestWednesdayBeforeDeparture = W.Date, PreviousFridayOfThatWednesday = DATEADD(DAY, -5, W.Date), -- Wednesday to Monday ClosestMondayBeforeDeparture = M.Date, PreviousWednesdayOfThatMonday = DATEADD(DAY, -5, M.Date), -- Check for odd/even IsOdd = CASE WHEN DATEPART(DAY, V.Departure) % 2 = 1 THEN 1 ELSE 0 END, -- Use previous expressions to build your collect periods Collect = CASE WHEN DATEPART(DAY, V.Departure) % 2 = 1 -- IsOdd THEN CONVERT(VARCHAR(100), DATEADD(DAY, -5, W.Date), 120) -- PreviousFridayOfThatWednesday + ' TO ' + CONVERT(VARCHAR(100), W.Date, 120) -- ClosestWednesdayBeforeDeparture ELSE -- IsEven CONVERT(VARCHAR(100), DATEADD(DAY, -5, M.Date), 120) -- PreviousWednesdayOfThatMonday + ' TO ' + CONVERT(VARCHAR(100), M.Date, 120) -- ClosestMondayBeforeDeparture END FROM SampleData AS V CROSS APPLY ( SELECT TOP 1 C.Date FROM #CalendarTable AS C WHERE C.Date < V.Departure AND C.Weekday = 3 -- 3: Wednesday ORDER BY C.Date DESC) AS W CROSS APPLY ( SELECT TOP 1 C.Date FROM #CalendarTable AS C WHERE C.Date < V.Departure AND C.Weekday = 1 -- 1: Monday ORDER BY C.Date DESC) AS M ORDER BY V.Departure
Departure   IsOdd   Collect                     ClosestWednesdayBeforeDeparture     PreviousFridayOfThatWednesday   ClosestMondayBeforeDeparture    PreviousWednesdayOfThatMonday
2018-12-01  1       2018-11-23 TO 2018-11-28    2018-11-28                          2018-11-23                      2018-11-26                      2018-11-21
2018-12-09  1       2018-11-30 TO 2018-12-05    2018-12-05                          2018-11-30                      2018-12-03                      2018-11-28
2018-12-25  1       2018-12-14 TO 2018-12-19    2018-12-19                          2018-12-14                      2018-12-24                      2018-12-19
2018-12-29  1       2018-12-21 TO 2018-12-26    2018-12-26                          2018-12-21                      2018-12-24                      2018-12-19
2019-01-02  0       2018-12-26 TO 2018-12-31    2018-12-26                          2018-12-21                      2018-12-31                      2018-12-26
2019-01-07  1       2018-12-28 TO 2019-01-02    2019-01-02                          2018-12-28                      2018-12-31                      2018-12-26
2019-01-10  0       2019-01-02 TO 2019-01-07    2019-01-09                          2019-01-04                      2019-01-07                      2019-01-02
CROSS APPLY(SELECT TOP 1 
            C.DATE
        FROM 
            #CALENDARTABLE C, SAMPLEDATA V
        WHERE
            C.DATE < V.DEPARTURE AND
            C.WEEKDAY = 1 
        ORDER BY
            C.DATE DESC) AS W

CROSS APPLY (SELECT TOP 1
            C.DATE
        FROM
            #CALENDARTABLE C,SAMPLEDATA V
        WHERE
            C.DATE < V.DEPARTURE AND
            C.WEEKDAY = 7 
        ORDER BY
            C.DATE DESC) AS M