Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/255.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
需要有关SQL server中日期查询的帮助吗?_Sql_Sql Server - Fatal编程技术网

需要有关SQL server中日期查询的帮助吗?

需要有关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 结果查询列是本周的日期。如果员工在这些日期没有休假,则应写上“可用”。否则,它应该写入休假类型 我对这种类型的查询非常陌生,请帮助我了解专家。您可以使用条件聚合来实

我在SQL Server中有两个表:

电磁脉冲 与colums EmpId一起度假,休假类型,开始日期,结束日期,重新加入日期 On_休假表存储休假员工的信息

我试图以这样一种方式查询表,即我的查询包含以下列:

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可能更容易。