Asp.net 选择DATEDIFF()中包含的MAX()

Asp.net 选择DATEDIFF()中包含的MAX(),asp.net,sql-server-2008,function,stored-procedures,Asp.net,Sql Server 2008,Function,Stored Procedures,我正在为我所在公司的桌面支持团队撰写报告。报表需要在ASP.NET应用程序传入的指定时间范围内生成一组新的启动器。目前,我们的Worker表和Contract表之间存在一对多关系。我们雇佣了很多承包商,他们有时会在几个月后回来,但仍然被视为新手,因为新机器需要与办公桌空间一起配置 每次工资审核、职位变更和新员工都会增加一份新合同。除了新的起动器外,我们需要过滤掉所有的。为工作变动和工资审查而添加的最新合同通常在前一个合同的结束日期后一天。由于我只是一个新的大计划的事情,我正在努力与一套功能,我正

我正在为我所在公司的桌面支持团队撰写报告。报表需要在ASP.NET应用程序传入的指定时间范围内生成一组新的启动器。目前,我们的Worker表和Contract表之间存在一对多关系。我们雇佣了很多承包商,他们有时会在几个月后回来,但仍然被视为新手,因为新机器需要与办公桌空间一起配置

每次工资审核、职位变更和新员工都会增加一份新合同。除了新的起动器外,我们需要过滤掉所有的。为工作变动和工资审查而添加的最新合同通常在前一个合同的结束日期后一天。由于我只是一个新的大计划的事情,我正在努力与一套功能,我正试图用以实现我的目标

WHERE    
(dbo.[Contract].StartDate BETWEEN @StartDateF AND @EndDateF) AND DATEDIFF(day, SELECT MAX(StartDate)FROM dbo.[Contract] WHERE dbo.[Contract].Worker_ID = w1.Worker_ID, SELECT MAX(EndDate)FROM dbo.[Contract] WHERE dbo.[Contract].Worker_ID = w1.Worker_ID)> 1 
我基本上想知道,在这个例子中,一个员工有多个合同,无论是离职还是离职,还是薪资审查,当前有效合同是否与前一个合同有一天不同。按照我的想法,这只会给我带来新的首发球员

麻烦的是,我仍然在试图弄清楚什么时候使用非select中的聚合函数,什么时候应用HAVING子句

请提供任何帮助,帮助我理解我的理解不足导致此查询/逻辑失败的原因

谢谢

编辑

好的,我仍然在抨击这个解决方案,这在语法上是不正确的。在试图消除一些歧义这里是查询,与更新

    Declare @StartDateF varchar(10)

    Set @StartDateF = '2012-08-03'

    Declare @EndDateF varchar(10)
    Set @EndDateF = '2012-09-04'


    SELECT w1.Worker_ID, w1.Title, w1.FirstName, w1.Surname,w1.Gender, w1.DateofBirth,
           dbo.[Contract].StartDate, (select w2.surname + ',' + w2.firstname from worker w2 WITH (NOLOCK) where w2.worker_ID = w1.manager)as Manager, dbo.Grade.GradeDescription AS JobTitle, dbo.Grade.Discipline,
           CASE WHEN dbo.[Contract].ContractType_ID = 1 OR dbo.[Contract].ContractType_ID = 2 OR dbo.[Contract].ContractType_ID = 5 OR dbo.[Contract].ContractType_ID = 6
           THEN 'Staff' ELSE 'Contractor' END AS ContractType
    FROM dbo.Worker w1 WITH (NOLOCK) inner join 
         dbo.[Contract] WITH (NOLOCK) ON  dbo.[Contract].Worker_ID = w1.Worker_ID inner join
         dbo.Grade WITH (NOLOCK) ON dbo.Grade.Grade_ID = dbo.[Contract].Grade_ID
    WHERE 

    (dbo.[Contract].StartDate BETWEEN @StartDateF AND @EndDateF AND EndDate IS NULL) 

    group by 
    w1.Worker_ID, w1.Title, w1.FirstName, w1.Surname,w1.Gender, w1.DateofBirth,
           dbo.[Contract].StartDate, manager,  dbo.Grade.Discipline,dbo.Grade.GradeDescription, dbo.[Contract].ContractType_ID

   Having DATEDIFF(day, SELECT MAX(StartDate)FROM dbo.[Contract] WHERE dbo.[Contract].Worker_ID = w1.Worker_ID, SELECT MAX(EndDate)FROM dbo.[Contract] WHERE dbo.[Contract].Worker_ID = w1.Worker_ID)
我已经添加了GROUPBY和having子句,但是现在我得到了以下错误

消息156,第15级,状态1,第24行 关键字“SELECT”附近的语法不正确。 Msg 102,15级,状态1,第24行 “,”附近的语法不正确。 Msg 102,15级,状态1,第24行 “')附近的语法不正确

毫无疑问,这些都与having子句中的函数有关。但我不明白这个问题有什么不对,这主要是个问题。我需要充分了解SQL函数,以便能够实现正确的解决方案

我在这里跟踪了DATEDIFF()函数

我可以看出,根据MS文档,在这个函数中使用函数是可以接受的

编辑

注释掉Having子句可以得到我期望的结果集。它向人们展示了合同变更(加薪)的情况,但这是任何人都不应该看到的信息,这些是现在唯一需要过滤掉的记录

编辑

我现在已经做了一些改进,克服了错误信息,但我仍然能找到加薪的人。下面是来自GROUPBY的修改后的查询

group by 
w1.Worker_ID, w1.Title, w1.FirstName, w1.Surname,w1.Gender, w1.DateofBirth,
       dbo.[Contract].StartDate, manager,  dbo.Grade.Discipline,dbo.Grade.GradeDescription, dbo.[Contract].ContractType_ID, w1.Worker_ID
Having

(((dbo.[Contract].StartDate BETWEEN @StartDateF AND @EndDateF) 
AND COUNT(dbo.[Contract].Worker_ID) = 1)

 OR 

 ((dbo.[Contract].StartDate BETWEEN @StartDateF AND @EndDateF) 
 AND DATEDIFF(day, (SELECT MAX(EndDate)FROM dbo.[Contract] WHERE dbo.[Contract].Worker_ID = w1.Worker_ID), (SELECT MAX(StartDate)FROM dbo.[Contract] WHERE dbo.[Contract].Worker_ID = w1.Worker_ID))>1))

要让员工签订多份合同,您可以使用:

select c.workerID
from Contract c
group by c.workerID
having count(distinct contractID) > 1
不过,听起来你只想数所有的东西,而不是新开始的。您可以通过以下方式完成此操作:

select w.workerID
from Contract c
where c.ContractType = 'New'
group by w.workerID
having count(distinct contractID) > 1
因为您没有提供表的外观、样本输入数据的外观以及希望实现的结果的详细信息,所以这是可以做到的最好的结果

    WHERE ( (dbo.[Contract].StartDate BETWEEN @StartDateF AND @EndDateF)AND dbo.[Contract].Worker_ID 
        IN (select worker_id from dbo.[Contract] 
        group by worker_id 
        having count(worker_id) = 1))

  OR 

   ((dbo.[Contract].StartDate BETWEEN @StartDateF AND @EndDateF) 
   AND DATEDIFF(day, (SELECT MAX(EndDate)FROM dbo.[Contract] WHERE dbo.[Contract].Worker_ID = w1.Worker_ID), (SELECT MAX(StartDate)FROM dbo.[Contract] WHERE dbo.[Contract].Worker_ID = w1.Worker_ID))>1 
   AND dbo.[Contract].Worker_ID = w1.Worker_ID )

现在对我有用:)

谢谢,是的,你是对的,没有足够的细节。我最糟糕的情况是按照您在第二个代码片段中概述的方式进行操作。目前,我们的合同类型表确定员工是否为全职、兼职、实习生、承包商等,我们没有列说明这是新的启动合同还是滚动合同。更改架构是我使用此新字段作为检查的解决方案。然而,这正是我试图避免的。不是出于任何主要原因,只是如果它是可以用一点SQL解决的问题,那么我完全支持。我同意让所有工人都有一份以上的合同,只是如果最新的合同(有开始日期和空结束日期)与前一份合同的结束日期不同一天。我试图使用DATEDIFF函数计算合同的MAX()开始日期,以获得上一个合同的最新日期和MAX()结束日期