SQL Server-昼夜分配

时间:2018-12-04 13:52:20

标签: sql-server

我有以下2019年数据。

top

以此类推。

我需要给一个记录一天,另一个给一个晚上值,并在整个一年的数据中重复一次,以便看起来像这样。

len

这是我的代码。

Date         Calendar_year Weekend_indicator
2019-01-01   2019          weekday
2019-01-01   2019          weekday
2019-01-02   2019          weekday
2019-01-02   2019          weekday

如何分配白天和黑夜的值并重复进行?

5 个答案:

答案 0 :(得分:2)

这个简单的查询可能会为您指明正确的方向:

USE TEMPDB

CREATE TABLE #T (DateCol DATE, Calender_Year INT)
INSERT INTO #T VALUES ('20180101', 2018 )

SELECT * 
FROM #T
CROSS APPLY (VALUES ('Day'), ('Night') ) AS C (Val)

答案 1 :(得分:2)

如果您只想更改代码而不重写它, 添加另一行,如下所示:

DECLARE @Year AS INT,
@FirstDateOfYear DATETIME,
@LastDateOfYear DATETIME
-- You can change @year to any year you desire
SELECT @year = 2019
SELECT @FirstDateOfYear = DATEADD(yyyy, @Year - 1900, 0)
SELECT @LastDateOfYear = DATEADD(yyyy, @Year - 1900 + 1, 0);
-- Creating Query to Prepare Year Data;
WITH cte AS (
SELECT 1 AS DayID,
@FirstDateOfYear AS FromDate,
DATENAME(dw, @FirstDateOfYear) AS Dayname
UNION ALL
SELECT cte.DayID + 1 AS DayID,
DATEADD(d, 1 ,cte.FromDate),
DATENAME(dw, DATEADD(d, 1 ,cte.FromDate)) AS Dayname
FROM cte
WHERE DATEADD(d,1,cte.FromDate) < @LastDateOfYear
)
SELECT c.FromDate AS Date
,@Year as calendar_year
,CHOOSE(datepart(dw, c.FromDate), 'WEEKEND', 'WEEKDAY', 'WEEKDAY', 
'WEEKDAY', 'WEEKDAY', 'WEEKDAY', 'WEEKEND') as weekend_indicator,
case tb.FromDate when 1 then 'Day' else 'Night' end as day_night -----<<<<<<-----
FROM CTE c
CROSS JOIN ( values (1), (2) ) tb (FromDate)
WHERE DayName IN ('Saturday','Sunday') 
or dayname not in ('Saturday', 'Sunday')
order by c.FromDate
OPTION (MaxRecursion 1000)

答案 2 :(得分:1)

我使用表变量创建此解决方案。

DECLARE 
     @Year int
    ,@FirstDateOfYear date
    ,@LastDateOfYear date
    ,@date_loop date

SET @YEAR = 2019

SELECT 
     @FirstDateOfYear = DATEADD(yyyy, @Year - 1900, 0)
    ,@LastDateOfYear = DATEADD(yyyy, @Year - 1900 + 1, 0)
    ,@date_loop = DATEADD(yyyy, @Year - 1900, 0) --initialize variable for loop

DECLARE @date_table TABLE ([Date] date, [Calendar_year] int, [Weekend_indicator] varchar(10), [day_night] varchar(5))

WHILE @date_loop < @LastDateOfYear
BEGIN
    INSERT @date_table

    SELECT d.[Date], d.[Calendar_year], d.[Weekend_indicator], ca.[day_night]
    FROM (
    SELECT  
         @date_loop AS [Date]
        ,YEAR(@date_loop) AS [Calendar_year]
        ,CHOOSE(datepart(dw, @date_loop), 'weekend', 'weekday', 'weekday','weekday', 'weekday', 'weekday', 'weekend') AS [Weekend_indicator]) AS d
    CROSS APPLY (
        SELECT 'Day' AS [day_night]
        UNION
        SELECT 'Night'
    ) AS ca

    SET @date_loop = DATEADD(day,1,@date_loop)
END

SELECT *
FROM @date_table

答案 3 :(得分:1)

修改后的答案:我看到一个未使用的(VALUES ...)子句,可以像这样使用:

CROSS JOIN (VALUES ('Day'), ('Night') ) whatever(day_night)

DB Fiddle

答案 4 :(得分:1)

如果没有日历或数字表,则可以使用临时表

示例

Declare @Date1 date = '2019-01-01'
Declare @Date2 date = '2019-12-31'

Select [Date] = d
      ,Calendar_year     = datepart(YEAR,d)
      ,Weekend_indicator = case when datename(WEEKDAY,d) in ('Saturday','Sunday') then 'weekend' else 'weekday' end
      ,day_night
 From  (
        Select Top (DateDiff(DAY,@Date1,@Date2)+1) D=DateAdd(DAY,-1+Row_Number() Over (Order By (Select Null)),@Date1) 
         From  master..spt_values n1,master..spt_values n2
       ) A
 Cross Join (values ('Day'),('Night') ) b(day_night)
 Order by D,day_night

返回

Date        Calendar_year  Weekend_indicator   day_night
2019-01-01  2019           weekday             Day
2019-01-01  2019           weekday             Night
2019-01-02  2019           weekday             Day
2019-01-02  2019           weekday             Night
...
2019-12-30  2019           weekday             Day
2019-12-30  2019           weekday             Night
2019-12-31  2019           weekday             Day
2019-12-31  2019           weekday             Night