以下函数返回给定员工的可用性列表。
有时,数据在同一日期的两行中保存在数据库中,所以我想对出现多次的日期执行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
我目前的工作是围绕GROUP BY MyAvailabilityDate并在SUM
列表中执行SELECT
。这只能在函数中直接实现时才能正常工作,但在直接查询函数时却无法正常工作。
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
答案 0 :(得分:1)
使用MAX()代替SUM()
SELECT MyAvailabilityDate, MAX(CAST(Night AS int)),MAX(CAST(Day as int)),MAX(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
答案 1 :(得分:0)
BITWISE OR aggregate可以使用下一个技巧进行模拟:
SELECT
MAX(field&1)+MAX(field&2)+MAX(field&4)+...+MAX(field&1073741824)+MIN(field&0x80000000) AS bitwise_or_of_field
FROM
tbl
(将省略号替换成两个缺失的省略号)
它非常冗余但有效。