我有员工出席的桌子。我希望获得特定月份的所有日期以及日期名称。我能够获取有关哪些数据存在的记录,但我想获得那些日期也不存在哪个员工或包含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
答案 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
如果这不是您期望的预期结果,请告诉我。
<小时/> <子> 的参考强>