基于白天获取所有日期 - sql

时间:2018-04-11 11:13:10

标签: sql sql-server date

我有开始日期,结束日期和日期名称。如何在sql中获取特定日期的这两个日期之间的所有日期?

示例数据:

  • 起始日期:2018年4月11日
  • end_date:5/11/2018
  • 天:星期一,星期四

预期输出:星期一和星期四开始和结束日期之间的所有日期,并将它们存储在表格中

更新 我目前的代码(不工作)

    public static void STOCKUPLOAD()
    {
        string data = "";
        data += "articles[0][article_id]" + "=" + "4654-AB-XG";
        data += "&";
        data += "articles[0][brand_id]" + "=" + "30";
        data += "&";
        data += "articles[0][quantity]" + "=" + "80";
        data += "&";
        data += "articles[0][prices][1]" + "=" + "5.30";
        data += "&";
        data += "articles[0][prices][3]" + "=" + "5.80";
        data += "&";
        data += "articles[0][prices][12]" + "=" + "5.99";
        data += "&";
        // ----------------------------------------------
        data += "articles[1][article_id]" + "=" + "AB8888-123";
        data += "&";
        data += "articles[1][brand_id]" + "=" + "80";
        data += "&";
        data += "articles[1][quantity]" + "=" + "35";
        data += "&";
        data += "articles[1][prices][1]" + "=" + "4.25";
        data += "&";
        data += "articles[1][prices][2]" + "=" + "6.30";
        data += "&";
        data += "articles[1][prices][8]" + "=" + "5";



        byte[] dataStream = Encoding.UTF8.GetBytes(data);
        WebRequest webRequest = WebRequest.Create(uri);

        webRequest.Method = "POST";
        webRequest.ContentType = "application/x-www-form-urlencoded";
        webRequest.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(auth_data));
        webRequest.ContentLength = dataStream.Length;

        Stream newStream = webRequest.GetRequestStream();

        // Send the data.
        newStream.Write(dataStream, 0, dataStream.Length);
        newStream.Close();
        WebResponse webResponse = webRequest.GetResponse();

        string raw_json;
        using (var sr = new StreamReader(webResponse.GetResponseStream()))
        {
            raw_json = sr.ReadToEnd();

            Rootobject ob = JsonConvert.DeserializeObject<Rootobject>(raw_json);

            if(ob.code == 1000)
            {
                System.Diagnostics.Debug.Print(ob.code_desc);
            }
        }
    }

6 个答案:

答案 0 :(得分:3)

在范围之间生成日期的另一种方法可能类似于以下查询。与CTEWHILE循环相比,这会更快。

DECLARE @StartDate DATETIME = '2018-04-11'
DECLARE @EndDate DATETIME = '2018-05-15'

SELECT @StartDate + RN AS DATE FROM
(   
    SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)))-1 RN 
    FROM   master..[spt_values] T1
) T 
WHERE RN <= DATEDIFF(DAY,@StartDate,@EndDate)
AND DATENAME(dw,@StartDate + RN) IN('Monday','Thursday')

注意:

如果master..[spt_values]中存在的行数不足以提供所提供的范围,则可以使用相同的交叉联接来获得更大的范围,如下所示。

SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)))-1 RN 
    FROM   master..[spt_values] T1
    CROSS JOIN master..[spt_values] T2

通过这种方式,您将能够在间隔为6436369天的范围之间生成日期。

答案 1 :(得分:2)

您可以使用recursive common table expression (CTE)生成天数列表。使用datepart(dw, ...),您可以过滤一周中的特定日期。

创建3月1日至今的星期一和星期四列表的示例:

create table ListOfDates (dt date);

with    cte as
        (
        select  cast('2018-03-01' as date) as dt  -- First day of interval
        union all
        select  dateadd(day, 1, dt)
        from    cte
        where   dt < getdate()  -- Last day of interval
        )
insert  into ListOfDates
        (dt)
select  dt
from    cte
where   datepart(dw, dt) in (2, 5)  -- 2=Monday and 5=Thursday
option  (maxrecursion 0)

See it working at SQL Fiddle.

答案 2 :(得分:1)

这对你有用:

DECLARE @table TABLE(
ID INT IDENTITY(1,1),
Date DATETIME,
Day VARCHAR(50)
)
DECLARE @Days TABLE(
ID INT IDENTITY(1,1),
Day VARCHAR(50)
)

INSERT INTO @Days VALUES ('Monday')
INSERT INTO @Days VALUES ('Thursday')




DECLARE @StartDate DATETIME='2018-01-01';
DECLARE @EndDate DATETIME=GETDATE();


DECLARE @Day VARCHAR(50)='Friday';

DECLARE @TempDate DATETIME=@StartDate;

WHILE CAST(@TempDate AS DATE)<=CAST(@EndDate AS DATE)
BEGIN

    IF EXISTS (SELECT 1 FROM @Days WHERE DAY IN (DATENAME(dw,@TempDate))) 
    BEGIN
        INSERT INTO @table
        VALUES  ( 
                  @TempDate, -- Date - datetime
                  DATENAME(dw,@TempDate)  -- Day - varchar(50)
                  )
    END

    SET @TempDate=DATEADD(DAY,1,@TempDate)
END



SELECT * FROM @table

答案 3 :(得分:1)

INSERT INTO TargetTab(dateCOL)    
SELECT dateCOL
    FROM tab
    WHERE dateCOL >= startdate AND dateCOL <= enddate 
    AND (DATENAME(dw,dateCOL) ='Thursday' OR DATENAME(dw,dateCOL) = 'Monday')

尝试此查询以获得结果。

答案 4 :(得分:1)

使用递归CTE生成日期,然后按工作日过滤。

SET DATEFIRST 1 -- 1: Monday, 7 Sunday

DECLARE @StartDate DATE = '2018-04-11'
DECLARE @EndDate DATE = '2018-05-15'

DECLARE @WeekDays TABLE (WeekDayNumber INT)

INSERT INTO @WeekDays (
    WeekDayNumber)
VALUES
    (1), -- Monday
    (4) -- Thursday

;WITH GeneratingDates AS
(
    SELECT
        GeneratedDate = @StartDate,
        WeekDay = DATEPART(WEEKDAY, @StartDate)

    UNION ALL

    SELECT
        GeneratedDate = DATEADD(DAY, 1, G.GeneratedDate),
        WeekDay = DATEPART(WEEKDAY, DATEADD(DAY, 1, G.GeneratedDate))
    FROM
        GeneratingDates AS G -- Notice that we are referencing a CTE that we are also declaring
    WHERE
        G.GeneratedDate < @EndDate
)
SELECT
    G.GeneratedDate
FROM
    GeneratingDates AS G
    INNER JOIN @WeekDays AS W ON G.WeekDay = W.WeekDayNumber
OPTION
    (MAXRECURSION 30000)

答案 5 :(得分:0)

试试这个:

declare @start date = '04-11-2018'
declare @end date = '05-11-2018'
declare @P_ID int = 1
declare @USER_ID int = 11
;with cte as(
    select @start [date]
    union all 
    select dateadd(DAY, 1, [date]) from cte
    where [date] < @end
)
--if MY_TABLE doesn't exist
select @P_ID,
       [date],
       'NOT SENT',
       cast(getdate() as date),
       @USER_ID
into MY_TABLE
from cte
--here you can specify days: 1 - Sunday, 2 - Monday, etc.
where DATEPART(dw,[date]) in (2, 5)
option (maxrecursion 0)

--if MY_TABLE does exist
--insert into MY_TABLE
--select @P_ID,
--       [date],
--     'NOT SENT',
--     cast(getdate() as date),
--     @USER_ID
--from cte
--where DATEPART(dw,[date]) in (2, 5)
--option (maxrecursion 0)