我想从2016年1月的第一天开始创建startdate,enddate和周数。一周的第一天是星期五。以下是我想要的示例。
设定星期的第一天是星期五
Start Date EndDate WeekNumber
1/1/2016 7/1/2016 1
8/1/2016 14/1/2016 2
15/1/2016 21/1/2016 3
…..
……
…..
30/12/2016 5/1/2017 53
6/1/2017 12/1/2017 1
13/1/2017 19/1/2017 2
20/1/2017 26/1/2017 3
…
….
…
请给我任何想法。
我可以通过这种方式在星期五的第一天
SET DATEFIRST 5
SELECT DATEADD(DAY, 1 - DATEPART(WEEKDAY, GETDATE()), CAST(GETDATE() AS DATE)) [WeekStart],
DATEADD(DAY, 7 - DATEPART(WEEKDAY, GETDATE()), CAST(GETDATE() AS DATE)) [WeekEnd]
以这种方式获得周数
SELECT { fn WEEK( '2016-01-01') }
答案 0 :(得分:1)
它在@StartDate和@StartDate + @NumYears之间产生了整周的系列:
您可以更改开始日期和结束日期,但请注意MAXRECURSION。
<html>
<head>
<title>Demo Model</title>
</head>
<body>
<?php
$_id = $_GET["id"];
$_time = $_GET["time"];
$_snr = $_GET["snr"];
$_station = $_GET["station"];
$_lat = $_GET["lat"];
$_lng = $_GET["lng"];
$_rssi = $_GET["rssi"];
$_data = $_GET["data"];
$_avgSnr = $_GET["avgSnr"];
if ( $fl = fopen('data.json','a')) {
fwrite($fl,"\"data\": { \"id\" : \"". $_id . "\", "
."\"data\" :\"" . $_data . "\", "
."\"from\" :\"" . $_station . "\", "
."\"lat\" :\"" . $_lat . "\", "
."\"lng\" :\"" . $_lng . "\" }\n" );
fclose($fl);
}
?>
</body>
</html>
或CREATE FUNCTION fnWeek(@StartDate DATETIME)
RETURNS @Weeks TABLE (StartWeekDate DATETIME, EndWeekDate DATETIME, WeekOfYear int)
AS
BEGIN
DECLARE @NumYears int = 2;
;WITH genDates
AS (
SELECT @StartDate AS mdate
UNION ALL
SELECT DATEADD(week, 1, mdate) FROM genDates WHERE DATEADD(week, 1, mdate) < DATEADD(year, @NumYears, @StartDate)
)
INSERT INTO @Weeks
SELECT mdate AS StartDate, DATEADD(day,6,mdate) AS EndDate, DATEPART(week, mdate) AS WeekOfYear
FROM genDates OPTION (MAXRECURSION 0);
RETURN;
END
GO
select * from fnWeek('2016-01-01');
可以添加为参数:
@NumYears
答案 1 :(得分:0)
首先,您需要一个函数来获取两个日期之间的日期,因此应创建以下函数:
CREATE FUNCTION [dbo].[GetDatesBetween](@dateFrom AS DATE, @dateTo AS DATE)
returns table as
return (
with
N0 as (SELECT 1 as n UNION ALL SELECT 1)
,N1 as (SELECT 1 as n FROM N0 t1, N0 t2)
,N2 as (SELECT 1 as n FROM N1 t1, N1 t2)
,N3 as (SELECT 1 as n FROM N2 t1, N2 t2)
,N4 as (SELECT 1 as n FROM N3 t1, N3 t2)
,N5 as (SELECT 1 as n FROM N4 t1, N4 t2)
,N6 as (SELECT 1 as n FROM N5 t1, N5 t2)
,nums as (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) as num FROM N6)
SELECT DATEADD(day,num-1,@dateFrom) as thedate
FROM nums
WHERE num <= DATEDIFF(day,@dateFrom,@dateTo) + 1
);
然后,执行以下查询以获得所需的结果:
DECLARE @dteFROM DATE = '2016-01-01'
DECLARE @dteTo DATE = '2017-01-26'
;WITH cteDaysInfo AS
(
SELECT theDate,
YEAR(thedate) YearValue,
DATEDIFF(day, CAST(YEAR(thedate) AS VARCHAR), CAST(YEAR(thedate) + 1 AS VARCHAR)) DaysInYear,
datediff(week, CAST(YEAR(thedate) AS VARCHAR), CAST(YEAR(thedate) + 1 AS VARCHAR)) NumberOfWeeksInYear,
ROW_NUMBER() OVER(ORDER BY theDate) DayNumberContinous,
DATEPART(dayofyear, thedate) DayNumber,
ceiling((ROW_NUMBER() OVER(ORDER BY theDate)) - 1) / 7 + 1 WeekNumberContinous,
DATEPART(WEEK, theDate) WeekNumber
FROM dbo.GetDatesBetween(@dteFROM, @dteTo)
)
, cteBaseWeeksInfo AS
(
SELECT YearValue,
(SELECT MIN(theDate) FROM cteDaysInfo t2 WHERE t2.YearValue = t1.YearValue and t2.WeekNumberContinous = t1.WeekNumberContinous) StartDate,
(SELECT MAX(theDate) FROM cteDaysInfo t2 WHERE t2.YearValue = t1.YearValue and t2.WeekNumberContinous = t1.WeekNumberContinous) EndDate,
t1.WeekNumberContinous,
(SELECT MIN(WeekNumber) FROM cteDaysInfo t2 WHERE t2.YearValue = t1.YearValue and t2.WeekNumberContinous = t1.WeekNumberContinous) WeekNumber
FROM cteDaysInfo t1
GROUP BY YearValue, WeekNumberContinous
)
SELECT (SELECT MIN(StartDate) FROM cteBaseWeeksInfo t2 WHERE t2.WeekNumberContinous = t1.WeekNumberContinous) StartDate,
(SELECT MAX(EndDate) FROM cteBaseWeeksInfo t2 WHERE t2.WeekNumberContinous = t1.WeekNumberContinous) EndDate,
(SELECT MAX(WeekNumber) FROM cteBaseWeeksInfo t2 WHERE t2.WeekNumberContinous = t1.WeekNumberContinous) EndDate
FROM cteBaseWeeksInfo t1
GROUP BY WeekNumberContinous
答案 2 :(得分:0)
以下解决方案不使用递归:
DECLARE @Year SMALLINT = 2016
DECLARE @FirstDayOfYear DATE = DATEFROMPARTS(@Year, 1, 1)
DECLARE @LastDayOfYear DATE = DATEFROMPARTS(@Year, 12, 31)
DECLARE @FirstFriday DATE = DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, '1900-01-01', @FirstDayOfYear), '1900-01-01'))
SET DATEFIRST 5
SELECT y.*, DATEPART(WEEK, y.FirstDayOfWeek) AS WeekNum
FROM (
SELECT FirstDayOfWeek = DATEADD(WEEK, v.number, @FirstFriday),
LastDayOfWeek = DATEADD(DAY, -1, DATEADD(WEEK, 1, DATEADD(WEEK, v.number, @FirstFriday)))
FROM master.dbo.spt_values v -- Instead of this system table, a tally table could be used with all numbers from 0 to 100/1000/10000/etc. (min 54 values: [0..53])
WHERE v.type = 'P' -- number = [0..2048]
AND v.number <= 53) AS y
WHERE @FirstDayOfYear <= y.LastDayOfWeek
AND y.FirstDayOfWeek <= @LastDayOfYear
2016年结果:
FirstDayOfWeek LastDayOfWeek WeekNum
-------------- ------------- -----------
2016-01-01 2016-01-07 1
2016-01-08 2016-01-14 2
2016-01-15 2016-01-21 3
2016-01-22 2016-01-28 4
2016-01-29 2016-02-04 5
...
2017年结果:
FirstDayOfWeek LastDayOfWeek WeekNum
-------------- ------------- -----------
2016-12-30 2017-01-05 53
2017-01-06 2017-01-12 2
2017-01-13 2017-01-19 3
2017-01-20 2017-01-26 4
2017-01-27 2017-02-02 5
...