我有一个问题,一个人在这里帮助开发,这给了很好的结果。我想在一个函数中使用这个查询,以后我想在一个过程中使用它。
CREATE FUNCTION [dbo].[fnGetWorkedDays] (@StartDate datetime, @EndDate datetime)
RETURNS int
AS
BEGIN
DECLARE @dateFrom datetime
DECLARE @dateTo datetime
SET @dateFrom = @StartDate
SET @dateTo = @EndDate
DECLARE @DAYSWORKED INT
SELECT @DAYSWORKED = (
SELECT EmpId, COUNT(*) as DaysWorked
FROM
(
SELECT DISTINCT EmpId,CAST(TimeIn AS DATE) AS [Date]
FROM myTable
WHERE TimeIn IS NOT NULL
AND CAST(TimeIn AS DATE) BETWEEN @StartDate AND @EndDate
)T
GROUP BY EmpId
ORDER BY EmpId)
RETURN ISNULL(@DAYSWORKED,0)
END
我得到的第一个错误是
Msg 1033, Level 15, State 1, Procedure fnGetWorkedDays, Line 24
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified.
我删除了ORDER BY然后又收到了另一个错误
Msg 116, Level 16, State 1, Procedure fnGetWorkedDays, Line 25
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
答案 0 :(得分:3)
我建议你去了解更多关于表值函数和标量值函数Difference between scalar, table-valued, and aggregate functions in SQL server?
关于你的场景,你应该为此编写一个表值函数,如下所示。
CREATE FUNCTION [dbo].[fnGetWorkedDays]
(
@StartDate AS DATETIME,
@EndDate datetime
)
RETURNS TABLE
AS
RETURN
SELECT EmpId, COUNT(*) as DaysWorked
FROM
(
SELECT DISTINCT EmpId,CAST(TimeIn AS DATE) AS [Date]
FROM myTable
WHERE TimeIn IS NOT NULL
AND CAST(TimeIn AS DATE) BETWEEN @StartDate AND @EndDate
)T
GROUP BY EmpId
要使用此功能,您可以编写如下的查询。
DECLARE @StartDate datetime
DECLARE @EndDate datetime
SET @StartDate = '2018-01-01'
SET @EndDate = '2018-01-31'
select * from [dbo].[fnGetWorkedDays](@StartDate,@EndDate)
如果您希望它作为标量值函数运行,那么您需要将EmpId
作为参数传递,如下所示。
CREATE FUNCTION [dbo].[fnGetWorkedDaysEmpWise]
(
@StartDate AS DATETIME,
@EndDate datetime,
@EmpId INT
)
RETURNS INT
AS
BEGIN
DECLARE @RetunCount INT
SELECT @RetunCount = COUNT(DISTINCT CAST(TimeIn AS DATE))
FROM myTable
WHERE TimeIn IS NOT NULL
AND CAST(TimeIn AS DATE) BETWEEN @StartDate AND @EndDate
AND EmpID=@EmpId
RETURN @RetunCount
END
您可以直接在select子句中使用它,如下所示。
DECLARE @StartDate datetime
DECLARE @EndDate datetime
SET @StartDate = '2018-01-01'
SET @EndDate = '2018-01-31'
SELECT [dbo].[fnGetWorkedDaysEmpWise](@StartDate,@EndDate,1)
答案 1 :(得分:0)
这就是你要找的。?
CREATE FUNCTION [dbo].[fnGetWorkedDays] (@StartDate datetime, @EndDate datetime)
RETURNS @DaysWorked TABLE
(
Empid Int,
DaysWorked Int
)
AS
BEGIN
insert into @DaysWorked (Empid,DaysWorked)
SELECT EmpId, COUNT(*) as DaysWorked
FROM
(
SELECT DISTINCT EmpId,CAST(TimeIn AS DATE) AS [Date]
FROM myTable
WHERE TimeIn IS NOT NULL
AND CAST(TimeIn AS DATE) BETWEEN @StartDate AND @EndDate
)T
GROUP BY EmpId
ORDER BY EmpId
RETURN
END
select * from [fnGetWorkedDays]('2018-01-01','2018-01-31')