SQL-联接中的条件列选择
我不确定是否可以使用TSQL实现此场景。我有一个叫做WorkingDays的表格,里面有这个信息SQL-联接中的条件列选择,sql,sql-server,sql-server-2008-r2,Sql,Sql Server,Sql Server 2008 R2,我不确定是否可以使用TSQL实现此场景。我有一个叫做WorkingDays的表格,里面有这个信息 ID | EmployeeId | Monday | Tuesday | Wednesday | Thursday | Friday ---------------------------------------------------------------------- 1 | 1 | 2 | 2 | 3 | 6
ID | EmployeeId | Monday | Tuesday | Wednesday | Thursday | Friday
----------------------------------------------------------------------
1 | 1 | 2 | 2 | 3 | 6 | 5
2 | 2 | 1 | 7 | 5 | 2 | 3
days列存储WorkingSchedule表的ID,该表有以下列:
ID int Primary Key
StartTime time
EndTime time
因此,我需要根据当前日期获取员工的开始时间和结束时间
我需要从查询中得到的是开始和结束时间,具体取决于日期。我要筛选的日期是使用getdate函数反当前日期
因此,需要选择正确的日期列名来进行联接
如何实现此方案?动态sql版本:
declare @sql nvarchar(max) ='
select
t.EmployeeId
, StarTime = max(case when t.rn=1 then '+quotename(datename(weekday,getdate()))+' end)
, EndTime = max(case when t.rn=2 then '+quotename(datename(weekday,getdate()))+' end)
from (
select *
, rn = row_number() over (partition by t.EmployeeId order by t.Id)
from t
) t
group by t.EmployeeId;'
exec sp_executesql @sql;
rextester演示:
返回:
+------------+----------+---------+
| EmployeeId | StarTime | EndTime |
+------------+----------+---------+
| 1 | 5 | 3 |
+------------+----------+---------+
+------------+---------+----------+---------+
| EmployeeId | WorkDay | StarTime | EndTime |
+------------+---------+----------+---------+
| 1 | Friday | 5 | 3 |
+------------+---------+----------+---------+
+----+------------+---------+-----------+------+
| Id | EmployeeId | WorkDay | StartEnd | Time |
+----+------------+---------+-----------+------+
| 1 | 1 | Friday | StartTime | 5 |
| 2 | 1 | Friday | EndTime | 3 |
+----+------------+---------+-----------+------+
根据您希望输出的方式,这里有两种不使用动态sql的其他方式:
两者都用于取消打印数据,WorkDay=datenameweekday,getdate用于获取当前WorkDay列
对于单行输出,我们添加了一些条件聚合:
/* one row per employeeId */
select
t.EmployeeId
, x.WorkDay
, StarTime = max(case when t.rn=1 then x.Time end)
, EndTime = max(case when t.rn=2 then x.Time end)
from (
select *
, rn = row_number() over (partition by t.EmployeeId order by t.Id)
from t
) t
cross apply (values
('Monday',Monday),('Tuesday',Tuesday),('Wednesday',Wednesday)
,('Thursday',Thursday),('Friday',Friday)
) x (WorkDay,Time)
where WorkDay = datename(weekday,getdate())
group by t.EmployeeId, x.WorkDay
返回:
+------------+----------+---------+
| EmployeeId | StarTime | EndTime |
+------------+----------+---------+
| 1 | 5 | 3 |
+------------+----------+---------+
+------------+---------+----------+---------+
| EmployeeId | WorkDay | StarTime | EndTime |
+------------+---------+----------+---------+
| 1 | Friday | 5 | 3 |
+------------+---------+----------+---------+
+----+------------+---------+-----------+------+
| Id | EmployeeId | WorkDay | StartEnd | Time |
+----+------------+---------+-----------+------+
| 1 | 1 | Friday | StartTime | 5 |
| 2 | 1 | Friday | EndTime | 3 |
+----+------------+---------+-----------+------+
如果希望输出为两行,如当前输出:
/* two rows per employeeId */
select
t.Id
, t.EmployeeId
, x.WorkDay
, t.StartEnd
, x.Time
from (
select *
, StartEnd = case
when row_number() over (partition by t.EmployeeId order by t.Id) = 1
then 'StartTime'
else 'EndTime'
end
from t
) t
cross apply (values
('Monday',Monday),('Tuesday',Tuesday),('Wednesday',Wednesday)
,('Thursday',Thursday),('Friday',Friday)
) x (WorkDay,Time)
where WorkDay = datename(weekday,getdate());
返回:
+------------+----------+---------+
| EmployeeId | StarTime | EndTime |
+------------+----------+---------+
| 1 | 5 | 3 |
+------------+----------+---------+
+------------+---------+----------+---------+
| EmployeeId | WorkDay | StarTime | EndTime |
+------------+---------+----------+---------+
| 1 | Friday | 5 | 3 |
+------------+---------+----------+---------+
+----+------------+---------+-----------+------+
| Id | EmployeeId | WorkDay | StartEnd | Time |
+----+------------+---------+-----------+------+
| 1 | 1 | Friday | StartTime | 5 |
| 2 | 1 | Friday | EndTime | 3 |
+----+------------+---------+-----------+------+
提示:datenameweekday,getdate返回当前区域设置中的工作日名称!这可能更好:
select wd.Employee, ws.StartTime, ws.EndTime
from WorkingDays wd
join WorkingSchedule ws on ws.Id = case datepart(weekday, getdate())
when 1 then wd.Monday
when 2 then wd.Tuesday
when 3 then wd.Wednesday
when 4 then wd.Thursday
when 5 then wd.Friday
else 0
end
但是,根据您的设置,您必须检查第0周、第1周的第一天。如果您可以根据上述数据提供示例输出,这将非常有用。workingdays表中的id是什么。如果是那个表id,那么同一个员工怎么可能包含两个不同的工作计划id,我是说同一个emp id有两行,每行只有一个员工!每个员工在每个工作日都有工作时间。所以问题很清楚。我们也不需要一个示例输出,因为问题是关于连接的方式,不是确切的结果。就我所知:好吧,我把这个问题读了好几遍,仍然没有任何线索+1