【发布时间】:2014-07-14 14:51:24
【问题描述】:
以下函数返回给定员工的可用性列表。
有时,数据在同一日期的两行下保存在数据库中,因此我想对出现多次的日期执行BITWISE OR (|)(例如:2014-11-27在以下结果中)
SELECT * FROM dbo.fnWebGetAvailability('10436837-7AA9-4012-BE66-CA33D0FA084D','2014-11-25','2014-11-30')
MyAvailabilityDate Night Day Evening NA Vacation
------------------ ----- ----- ------- ----- --------
2014-11-25 0 1 1 0 0
2014-11-26 0 0 0 0 0
2014-11-27 0 0 1 0 0
2014-11-27 1 0 0 0 0
2014-11-28 0 0 0 0 0
2014-11-29 0 0 0 0 0
2014-11-30 0 0 0 0 0
我目前的工作是按 MyAvailabilityDate 分组并在SELECT 列表中执行SUM。这只有在直接在函数中实现时才能正常工作,但在直接查询函数时不起作用。
SELECT MyAvailabilityDate, SUM(CAST(Night AS int)),SUM(CAST(Day as int)),SUM(CAST(Evening as int)),NA,Vacation
FROM dbo.fnWebGetAvailability('10436837-7AA9-4012-BE66-CA33D0FA084D','2014-11-25','2014-11-30') GROUP BY MyAvailabilityDate,CAST(Night AS int),CAST(Day as int),CAST(Evening as int),NA,Vacation
我不喜欢这种实现,因为需要将列数据类型从 BIT 更改为 INT,而且我以后必须记住使用 >= 1 而不仅仅是 = 1。
直接查询我的函数时如何使用BITWISE OR?
编辑:我认为没有必要,但这里是函数的代码:
USE [MyDataBase]
GO
/****** Object: UserDefinedFunction [dbo].[fnWebGetAvailability] Script Date: 2014-07-14 10:51:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[fnWebGetAvailability]
(
@MyUserID Uniqueidentifier
,@MyAvailabilityDateFrom DATE
,@MyAvailabilityDateTo DATE
)
RETURNS @MaTable TABLE
(
MyAvailabilityDate DATE,
Night INT,
Day INT,
Evening INT,
NA INT,
Vacation INT
)
AS
BEGIN
DECLARE @MyUserStreamID UNIQUEIDENTIFIER = (SELECT ID FROM UserStreams WHERE USerID = @MyUserID AND DefaultStream = 1)
INSERT INTO @MaTable
SELECT dt.Date AS MyAvailabilityDate
,SUM(ISNULL(CAST(usd.N AS int),0)) AS Night
,SUM(ISNULL(CAST(usd.J AS int),0)) AS Day
,SUM(ISNULL(CAST(usd.S AS int),0)) AS Evening
,CASE WHEN EXISTS (SELECT NULL FROM UserHolidays as us1 WHERE us1.UserStreamID = @MyUserStreamID AND us1.FromDate = dt.date AND (Description IS NULL OR Description LIKE '')) THEN 1
ELSE 0 END AS NA
,CASE WHEN EXISTS (SELECT NULL FROM UserHolidays as us2 WHERE us2.UserStreamID = @MyUserStreamID AND us2.FromDate = dt.date AND Description LIKE 'Vacation') THEN 1
ELSE 0 END AS Vacation
FROM dbo.fnDatesTable(@MyAvailabilityDateFrom,@MyAvailabilityDateTo) As dt
LEFT JOIN UserSpecialDays as usd on dt.Date = usd.FromDate and usd.UserStreamId = @MyUserStreamID
LEFT JOIN UserHolidays as uh on dt.Date = uh.FromDate and uh.UserStreamId = @MyUserStreamID
GROUP BY dt.Date
RETURN
END
GO
【问题讨论】:
标签: sql sql-server tsql bit-manipulation user-defined-functions