显示月份的所有日期以及日期名称

时间:2018-05-23 11:28:19

标签: sql sql-server

我有员工出席的桌子。我希望获得特定月份的所有日期以及日期名称。我能够获取有关哪些数据存在的记录,但我想获得那些日期也不存在哪个员工或包含NULL的日期。

DROP TABLE [Attendance];
DROP TABLE [Employee];


CREATE TABLE [Employee]
(
[ID] Int NOT NULL PRIMARY KEY,
[FirstName] Varchar(25)
)

INSERT INTO [Employee] VALUES (1, 'Asim');

CREATE TABLE [Attendance]
(
ID Int NOT NULL PRIMARY KEY,
[Date] Date,
Status Varchar(25),
[EmpCode] Int,
CONSTRAINT FK_EmpCode FOREIGN KEY ([EmpCode])
REFERENCES [Employee](ID)
)

INSERT INTO [Attendance] VALUES (1, '2018-05-02', 'Present', 1);
INSERT INTO [Attendance] VALUES (2, '2018-05-03', 'Present', 1);
INSERT INTO [Attendance] VALUES (3, '2018-05-04', 'Present', 1);
INSERT INTO [Attendance] VALUES (4, '2018-05-07', 'Present', 1);
INSERT INTO [Attendance] VALUES (5, '2018-05-09', 'Present', 1);
INSERT INTO [Attendance] VALUES (6, '2018-05-10', 'Present', 1);
INSERT INTO [Attendance] VALUES (7, '2018-05-11', 'Present', 1);
INSERT INTO [Attendance] VALUES (8, '2018-05-14', 'Present', 1);
INSERT INTO [Attendance] VALUES (9, '2018-05-15', 'Present', 1);
INSERT INTO [Attendance] VALUES (10, '2018-05-16', 'Present', 1);



DECLARE @month AS INT = 5
DECLARE @Year AS INT = 2018
;WITH N(N)AS 
(
SELECT 1 FROM(VALUES(1),(1),(1),(1),(1),(1),(1))M(N)),
tally(N) AS(SELECT ROW_NUMBER()OVER(ORDER BY N.N)FROM N,N a)
SELECT N DAYNUMBER, datefromparts(@year,@month,N) DATE, DATENAME(weekday, datefromparts(@year,@month,N)) DATEDAY,
[Info].[FirstName], 

Att.date [Date],
DATENAME(month, att.date) AS 'Month Name'

FROM 
[Employee] [Info], [Attendance] [Att], tally

WHERE 
info.id = att.empcode and
 N <= day(EOMONTH(datefromparts(@year,@month,1))) 
AND DATENAME(month, Att.Date) = 'May' 
AND datefromparts(@year,@month,N) = att.date

GROUP BY
[Info].[FirstName], tally.N,
[Att].[Date]

ORDER BY [Att].[Date]

这是我到目前为止所尝试的。任何人都可以看看并指导我正确的方向吗?

结果现在看起来像这样,虽然我希望错过的日子按顺序显示。

DAYNUMBER            DATE       DATEDAY                        FirstName                 Date       Month Name
-------------------- ---------- ------------------------------ ------------------------- ---------- ------------------------------
2                    2018-05-02 Wednesday                      Asim                      2018-05-02 May
3                    2018-05-03 Thursday                       Asim                      2018-05-03 May
4                    2018-05-04 Friday                         Asim                      2018-05-04 May
7                    2018-05-07 Monday                         Asim                      2018-05-07 May
9                    2018-05-09 Wednesday                      Asim                      2018-05-09 May
10                   2018-05-10 Thursday                       Asim                      2018-05-10 May
11                   2018-05-11 Friday                         Asim                      2018-05-11 May
14                   2018-05-14 Monday                         Asim                      2018-05-14 May
15                   2018-05-15 Tuesday                        Asim                      2018-05-15 May
16                   2018-05-16 Wednesday                      Asim                      2018-05-16 May

2 个答案:

答案 0 :(得分:2)

试试这种方式。我没有添加所有联接,请根据您的需要进行更新。

usr.username

答案 1 :(得分:2)

试试这个......

DECLARE @dt1 DATETIME= (SELECT TOP 1 [date] FROM attendance ORDER BY [date] ASC) 
DECLARE @dt2 DATETIME= (SELECT TOP 1 [date] FROM attendance ORDER BY [date] DESC) 

;WITH ctedaterange 
     AS (SELECT [date]=@dt1 
         UNION ALL 
         SELECT [date] + 1 
         FROM   ctedaterange 
         WHERE  [date] + 1 <= @dt2) 


SELECT Datepart(day, t1.[date])             AS [DAYNUMBER], 
       CONVERT(VARCHAR(10), t1.[date], 120) AS [Date], 
       Datename(dw, t1.[date])              AS [DATEDAY], 
       t3.firstname                         AS [FirstName],  
       Datename(month, t1.[date])           AS [MonthName] 

FROM   ctedaterange T1 
       LEFT JOIN attendance T2 ON t1.[date]  = t2.[date] 
       LEFT JOIN employee   T3 ON t2.empcode = t3.id 
OPTION (maxrecursion 0) 

输出

+-----------+------------+-----------+-----------+-----------+
| DAYNUMBER |    Date    |  DATEDAY  | FirstName | MonthName |
+-----------+------------+-----------+-----------+-----------+
|         2 | 2018-05-02 | Wednesday | Asim      | May       |
|         3 | 2018-05-03 | Thursday  | Asim      | May       |
|         4 | 2018-05-04 | Friday    | Asim      | May       |
|         5 | 2018-05-05 | Saturday  | NULL      | May       |
|         6 | 2018-05-06 | Sunday    | NULL      | May       |
|         7 | 2018-05-07 | Monday    | Asim      | May       |
|         8 | 2018-05-08 | Tuesday   | NULL      | May       |
|         9 | 2018-05-09 | Wednesday | Asim      | May       |
|        10 | 2018-05-10 | Thursday  | Asim      | May       |
|        11 | 2018-05-11 | Friday    | Asim      | May       |
|        12 | 2018-05-12 | Saturday  | NULL      | May       |
|        13 | 2018-05-13 | Sunday    | NULL      | May       |
|        14 | 2018-05-14 | Monday    | Asim      | May       |
|        15 | 2018-05-15 | Tuesday   | Asim      | May       |
|        16 | 2018-05-16 | Wednesday | Asim      | May       |
+-----------+------------+-----------+-----------+-----------+

SQL在线演示:http://sqlfiddle.com/#!18/24038/5/0

如果这不是您期望的预期结果,请告诉我。

<小时/> <子> 的参考
1. http://www.sqlservergeeks.com/generate-list-dates-between-date-range/