2012-02-04 64 views
0

我有一个查询,如下所示:我怎么能这个SQL转换为HQL查询

WITH CTE AS (
    SELECT MIN(att.Date) [minDate] 
    FROM Attendance att 
    WHERE att.Date between '12/01/2011 00:00:00' 
    AND '12/31/2011 00:00:00' 
    AND att.EmpID = 4700 
    GROUP BY EmpID, CONVERT(VARCHAR, att.Date , 111) 
    HAVING MIN(CONVERT(VARCHAR, att.Date , 8)) > '09:00:00') 
SELECT COUNT(minDate) FROM CTE 

我需要一个C#应用程序使用它,但我不能只使用查询,因为它说,查询必须以select或from关键字开头。我需要此查询才能在HQL中工作。请帮忙。

回答

1

最后将其与这些

SELECT count(att.AttDate) 
from Attendance att 
where att.Employee.EmployeeCD = "+ empCD +" 
and att.AttDate IN 
    (SELECT MIN(att.AttDate) 
    from Attendance att 
    where att.AttDate between '" + startDate.Date + "' and '" + endDate.Date + "' 
    and att.Employee.EmployeeCD = " + empCD + " 
    GROUP BY EmployeeCD, CONVERT(VARCHAR,att.AttDate, 111) 
    having min(CONVERT(VARCHAR, att.AttDate, 8)) > '08:10:00') 
1

你必须重写查询。

在结果中,我们根本不关心日期,我们对通用结果感兴趣的是什么,所以我们可以从select中删除日期并将其替换为EmpId *。

SELECT EmpID 
    FROM Attendance att 
    WHERE att.Date between '12/01/2011 00:00:00' 
    AND '12/31/2011 00:00:00' 
    AND att.EmpID = 4700 
    GROUP BY EmpID, CONVERT(VARCHAR, att.Date , 111) 
    HAVING MIN(CONVERT(VARCHAR, att.Date , 8)) > '09:00:00') 

不,我们可以改变这个问题。

SELECT COUNT(EmpID) FROM Attendance WHERE EmpID IN (
    SELECT EmpID 
     FROM Attendance att 
     WHERE att.Date between '12/01/2011 00:00:00' 
     AND '12/31/2011 00:00:00' 
     AND att.EmpID = 4700 
     GROUP BY EmpID, CONVERT(VARCHAR, att.Date , 111) 
     HAVING MIN(CONVERT(VARCHAR, att.Date , 8)) > '09:00:00') 
); 

第二个查询仅改写CTE表达式,在大多数情况下,它只是语法糖。将其转换为HQL应该不成问题。

*我假定EmpID是唯一的。

+0

工作是,EMPID是uniq的。并非常感谢您的帮助。但查询结果将随该empID的所有行而出现,而不考虑所有条件。我只需要计算出现在你的第一个查询中的行。 plz帮助。 – Almaji 2012-02-04 09:54:35

+0

第一个可能会这样做,但第二个会返回计数。但是对于你给出的例子,结果将是null或1.因此,如果查询的条件是正确的,你根本不需要那么多的计数。 – 2012-02-04 13:55:06

+0

让我详细说明。 emp 4700在他的工作生涯中有500天的参与。根据所有条件,第二个查询结果假设返回的出勤次数在12/1到12/31之间。所以它假设返回最好不到31?但查询结果是500.他的总出席人数。怎么办? – Almaji 2012-02-04 20:52:55