SQL-联接中的条件列选择

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

我不确定是否可以使用TSQL实现此场景。我有一个叫做WorkingDays的表格,里面有这个信息

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