需要有关SQL server中日期查询的帮助吗?
我在SQL Server中有两个表: 电磁脉冲 与colums EmpId一起度假,休假类型,开始日期,结束日期,重新加入日期 On_休假表存储休假员工的信息 我试图以这样一种方式查询表,即我的查询包含以下列:需要有关SQL server中日期查询的帮助吗?,sql,sql-server,Sql,Sql Server,我在SQL Server中有两个表: 电磁脉冲 与colums EmpId一起度假,休假类型,开始日期,结束日期,重新加入日期 On_休假表存储休假员工的信息 我试图以这样一种方式查询表,即我的查询包含以下列: EmpId, 24-1-2016, 25-1-2016, 26-1-2016, 27-1-2016, 28-1-2016 结果查询列是本周的日期。如果员工在这些日期没有休假,则应写上“可用”。否则,它应该写入休假类型 我对这种类型的查询非常陌生,请帮助我了解专家。您可以使用条件聚合来实
EmpId, 24-1-2016, 25-1-2016, 26-1-2016, 27-1-2016, 28-1-2016
结果查询列是本周的日期。如果员工在这些日期没有休假,则应写上“可用”。否则,它应该写入休假类型
我对这种类型的查询非常陌生,请帮助我了解专家。您可以使用条件聚合来实现这一点:
select e.empid,
coalesce(max(case when '2016-01-24' between v.startdate and v.enddate
then leave_type end),
'available') as [2016-01-14],
coalesce(max(case when '2016-01-25' between v.startdate and v.enddate
then leave_type end),
'available') as [2016-01-15],
. . .
from emp e left join
from vacation v
on e.empid = v.empid
group by e.empid;
您可以使用条件聚合执行此操作:
select e.empid,
coalesce(max(case when '2016-01-24' between v.startdate and v.enddate
then leave_type end),
'available') as [2016-01-14],
coalesce(max(case when '2016-01-25' between v.startdate and v.enddate
then leave_type end),
'available') as [2016-01-15],
. . .
from emp e left join
from vacation v
on e.empid = v.empid
group by e.empid;
如果没有动态sQL,就无法更改列名,这会使问题变得复杂。 下面是另一个建议:将日期表更改为包含一周中某一天的名称,如下所示:
CREATE TABLE DaysWeeks
(CalYear SMALLINT NOT NULL,
WeekNumber TINYINT NOT NULL,
CalDate DATE NOT NULL,
DayOfWeekNumber TINYINT,
DayOfWeekName VARCHAR(9)
CONSTRAINT PK_DaysWeeks PRIMARY KEY CLUSTERED (CalYear, WeekNumber, CalDate)
)
INSERT INTO dbo.DaysWeeks
( CalYear, WeekNumber, CalDate,DayOfWeekNumber,DayOfWeekName )
VALUES ( 2016, 4, '01/24/2016',1,'Sunday'),
( 2016, 4, '01/25/2016',2,'Monday'),
( 2016, 4, '01/26/2016',3,'Tuesday'),
( 2016, 4, '01/27/2016',4,'Wednesday'),
( 2016, 4, '01/28/2016',5,'Thursday'),
( 2016, 4, '01/29/2016',6,'Friday'),
( 2016, 4, '01/30/2016',7,'Saturday')
有这样的价值观:
CREATE TABLE DaysWeeks
(CalYear SMALLINT NOT NULL,
WeekNumber TINYINT NOT NULL,
CalDate DATE NOT NULL,
DayOfWeekNumber TINYINT,
DayOfWeekName VARCHAR(9)
CONSTRAINT PK_DaysWeeks PRIMARY KEY CLUSTERED (CalYear, WeekNumber, CalDate)
)
INSERT INTO dbo.DaysWeeks
( CalYear, WeekNumber, CalDate,DayOfWeekNumber,DayOfWeekName )
VALUES ( 2016, 4, '01/24/2016',1,'Sunday'),
( 2016, 4, '01/25/2016',2,'Monday'),
( 2016, 4, '01/26/2016',3,'Tuesday'),
( 2016, 4, '01/27/2016',4,'Wednesday'),
( 2016, 4, '01/28/2016',5,'Thursday'),
( 2016, 4, '01/29/2016',6,'Friday'),
( 2016, 4, '01/30/2016',7,'Saturday')
现在,您可以有一个基于一周中的某一天进行数据透视的查询:
WITH cte AS (
SELECT EmpDays.Employee, EmpDays.CalDate, EmpDays.DoWName, ISNULL(v.Leave_Type,'Available') AS Available
FROM dbo.On_Vacation v
RIGHT OUTER JOIN
(SELECT e.EmpID AS Employee, dw.CalDate AS CalDate, dw.DayOfWeekName AS DoWName
FROM dbo.DaysWeeks dw,
dbo.Employee e
WHERE dw.CalYear = 2016 AND dw.WeekNumber = 4) AS EmpDays
ON
v.EmpID = EmpDays.Employee
AND v.StartingFrom <= empdays.CalDate
AND v.EndingTo >= empdays.CalDate
)
SELECT * FROM cte
PIVOT (MAX(cte.Available) FOR DoWName IN (['Sunday'],['Monday'],['Tuesday'],['Wednesday'],['Thursday'],['Friday'],['Saturday'])
如果您真的需要列中的实际日期,我会将其调整为使用动态SQL。但是在这样做之前,IMHO,这会使代码更难阅读和维护,不是因为这很简单,我想问一下您将如何显示数据,因此是否可以在报表或表示层中处理这些数据。如果没有动态sQL,您无法更改列名,这会使问题变得复杂。 下面是另一个建议:将日期表更改为包含一周中某一天的名称,如下所示:
CREATE TABLE DaysWeeks
(CalYear SMALLINT NOT NULL,
WeekNumber TINYINT NOT NULL,
CalDate DATE NOT NULL,
DayOfWeekNumber TINYINT,
DayOfWeekName VARCHAR(9)
CONSTRAINT PK_DaysWeeks PRIMARY KEY CLUSTERED (CalYear, WeekNumber, CalDate)
)
INSERT INTO dbo.DaysWeeks
( CalYear, WeekNumber, CalDate,DayOfWeekNumber,DayOfWeekName )
VALUES ( 2016, 4, '01/24/2016',1,'Sunday'),
( 2016, 4, '01/25/2016',2,'Monday'),
( 2016, 4, '01/26/2016',3,'Tuesday'),
( 2016, 4, '01/27/2016',4,'Wednesday'),
( 2016, 4, '01/28/2016',5,'Thursday'),
( 2016, 4, '01/29/2016',6,'Friday'),
( 2016, 4, '01/30/2016',7,'Saturday')
有这样的价值观:
CREATE TABLE DaysWeeks
(CalYear SMALLINT NOT NULL,
WeekNumber TINYINT NOT NULL,
CalDate DATE NOT NULL,
DayOfWeekNumber TINYINT,
DayOfWeekName VARCHAR(9)
CONSTRAINT PK_DaysWeeks PRIMARY KEY CLUSTERED (CalYear, WeekNumber, CalDate)
)
INSERT INTO dbo.DaysWeeks
( CalYear, WeekNumber, CalDate,DayOfWeekNumber,DayOfWeekName )
VALUES ( 2016, 4, '01/24/2016',1,'Sunday'),
( 2016, 4, '01/25/2016',2,'Monday'),
( 2016, 4, '01/26/2016',3,'Tuesday'),
( 2016, 4, '01/27/2016',4,'Wednesday'),
( 2016, 4, '01/28/2016',5,'Thursday'),
( 2016, 4, '01/29/2016',6,'Friday'),
( 2016, 4, '01/30/2016',7,'Saturday')
现在,您可以有一个基于一周中的某一天进行数据透视的查询:
WITH cte AS (
SELECT EmpDays.Employee, EmpDays.CalDate, EmpDays.DoWName, ISNULL(v.Leave_Type,'Available') AS Available
FROM dbo.On_Vacation v
RIGHT OUTER JOIN
(SELECT e.EmpID AS Employee, dw.CalDate AS CalDate, dw.DayOfWeekName AS DoWName
FROM dbo.DaysWeeks dw,
dbo.Employee e
WHERE dw.CalYear = 2016 AND dw.WeekNumber = 4) AS EmpDays
ON
v.EmpID = EmpDays.Employee
AND v.StartingFrom <= empdays.CalDate
AND v.EndingTo >= empdays.CalDate
)
SELECT * FROM cte
PIVOT (MAX(cte.Available) FOR DoWName IN (['Sunday'],['Monday'],['Tuesday'],['Wednesday'],['Thursday'],['Friday'],['Saturday'])
如果您真的需要列中的实际日期,我会将其调整为使用动态SQL。但是在这样做之前,IMHO,这使得代码更难阅读和维护,并不是说这很简单,我会问您将如何显示数据,因此是否可以在报告或表示层中处理这些数据。创建一个真实或动态日历表,每个日期一行,然后将其与假日表连接起来。在你得到结果后,你可以把它转成不同的布局。谢谢詹姆斯。但是,我需要日期作为列?这就是从On_vacation OV中选择OV.empid、IIFov.StartingDate='2016-01-24',OV.VacationType、'Available'作为[2016-01-24]的轴心所在。我可以得到一个特定日期所需的结果,但是,我需要一周的相同结果。这就是日历表的用途。创建一个真实的或动态的日历表,每个日期一行,然后将其与您的假日表合并。在你得到结果后,你可以把它转成不同的布局。谢谢詹姆斯。但是,我需要日期作为列?这就是从On_vacation OV中选择OV.empid、IIFov.StartingDate='2016-01-24',OV.VacationType、'Available'作为[2016-01-24]的轴心所在。我能得到一个特定日期所需的结果,但是,我需要一周相同的结果。这就是Hanks Gordon的日历表,这很好。但是,如何在我将日期保存在另一个表中时动态使用日期。TableName:dates and Weeks,它有两列1.Date和2。威克诺。如果我只给出weekno,那么上面的查询应该针对该周的所有日期运行,而不是写入每个日期,这有什么办法吗?@Programmer2015。动态约会是一个更难的问题,而不是你问的问题。你可以问另一个问题,但谷歌sql server dynamic pivot可能更容易。谢谢Gordon,这很好用。但是,如何在我将日期保存在另一个表中时动态使用日期。TableName:dates and Weeks,它有两列1.Date和2。威克诺。如果我只给出weekno,那么上面的查询应该针对该周的所有日期运行,而不是写入每个日期,这有什么办法吗?@Programmer2015。动态约会是一个更难的问题,而不是你问的问题。您可以问另一个问题,但只需使用google sql server dynamic pivot可能更容易。