Reputation: 507
The following function returns a list of availability for a given employee.
Sometimes, the data was saved in the database under two lines for the same date so I would like to perform a BITWISE OR
(|) for the dates that are present more than one time (eg: 2014-11-27 in the following results)
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
My current work arround was to GROUP BY MyAvailabilityDate and perform a SUM
in the SELECT
list. That's only working correctly when implemented directly in the function but not working when querying directly the function.
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
I don't like this implementation because the columns data type needed to be changed from BIT to INT and I'll later have to remember to use >= 1
instead of just = 1
.
How can I use BITWISE OR
when querying directly my function ?
Edit: I don't think it is necessary but here's the code of the function:
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
Upvotes: 0
Views: 63
Reputation: 31
BITWISE OR aggregate can be simulated using next trick:
SELECT
MAX(field&1)+MAX(field&2)+MAX(field&4)+...+MAX(field&1073741824)+MIN(field&0x80000000) AS bitwise_or_of_field
FROM
tbl
(replace ellipsis with other missing powers of two)
It's very redundantly but works.
Upvotes: 0
Reputation: 10908
Use MAX() instead of 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
Upvotes: 1