How can I achieve this? I am getting an error incorrect syntax near between
#STARTDATE, #ENDDATE, #CREATEDDATE -- INPUT PARAMETERS
SELECT *
FROM [DBO].[xxx] x
INNER JOIN [DBO].[yyy] y
ON x.ID = y.ID
AND CASE WHEN #CREATEDDATE = 1
THEN x.CreatedDate BETWEEN #STARTDATE AND #ENDDATE
WHEN #CREATEDDATE = 0
THEN x.ClosedDate BETWEEN #STARTDATE AND #ENDDATE
SQL Server does not treat boolean expressions as something that a case expression can return. In fact, case in on and where clauses is to be discouraged. And you can easily express this using more basic boolean operations:
SELECT *
FROM [DBO].[xxx] x INNER JOIN
[DBO].[yyy] y
ON x.ID = y.ID AND
( (#CREATEDDATE = 1 AND x.CreatedDate BETWEEN #STARTDATE AND #ENDDATE) OR
(#CREATEDDATE = 0 AND x.ClosedDate BETWEEN #STARTDATE AND #ENDDATE)
)
You can try the following query
SELECT *
FROM [DBO].[xxx] x
INNER JOIN [DBO].[yyy] y
ON x.ID = y.ID
AND CASE WHEN #CREATEDDATE = 1 AND x.CreatedDate BETWEEN #STARTDATE AND #ENDDATE THEN 1
WHEN #CREATEDDATE = 0 AND x.ClosedDate BETWEEN #STARTDATE AND #ENDDATE THEN 1
ELSE 0 END = 1
Related
In the below code I don't want the second part of the join condition to be applicable if #selectAll = 1
(ie and (listMap.dateOfTask between #startDate and #endDate)
I am using SQL Server.
#userId nvarchar(200),
#startDate nvarchar(200),
#endDate nvarchar(200),
#selectAll bit
select
*
from tmListMap l
right join tmTime t
on
l.timeId = t.timeId
and (l.dateOfTask between #startDate and #endDate) //Don’t need this condition if #selectAll = 1
#Damien suggested you need a or condition like
#userId nvarchar(200),
#startDate nvarchar(200),
#endDate nvarchar(200),
#selectAll bit
select
*
from tmListMap l
right join tmTime t
on
l.timeId = t.timeId
and ((l.dateOfTask between #startDate and #endDate) or #selectAll=1)
#userId nvarchar(200),
#startDate nvarchar(200),
#endDate nvarchar(200),
#selectAll bit
select
*
from tmListMap l
right join tmTime t
on
l.timeId = t.timeId
where #selectAll = 1 or (l.dateOfTask between #startDate and #endDate)
Two options.
Option A as OR clause
#startDate date,
#endDate date,
#selectAll bit
select
*
from tmListMap l
right join tmTime t
on l.timeId = t.timeId
WHERE
(
l.dateOfTask between #startDate and #endDate and #selectAll = 0
OR
#selectAll = 1
)
Option B as UNION ALL
#startDate date,
#endDate date,
#selectAll bit
select
*
from tmListMap l
right join tmTime t
on l.timeId = t.timeId
WHERE #selectAll = 0
and l.dateOfTask between #startDate and #endDate
UNION ALL
select
*
from tmListMap l
right join tmTime t
on l.timeId = t.timeId
WHERE #selectAll = 1
Depends a bit on your data which will be faster. In my experience the UNION ALL scales better. As long as the different parts are absolutely not able to create duplicates.
I have 4 tables that I am trying to get data from yet my join statement returns null. I have tried full, left and right joins with no success. Below I have provided my code and the diagram, the table that returns null values is the ChannelData table. I am trying to sum the Vvalue from this table, when i add the condition that i commented out below i.e.between start and end date` my query return no results. I know there must be a problem with my joins but I have tried everything. This table is not normalized properly and I have to use it as is:
DECLARE #bp varchar(4)
DECLARE #priority varchar(2)
DECLARE #startDate datetime
DECLARE #endDate datetime
SET #bp = 1710
SET #priority = 2
SET #endDate = (SELECT EndDate FROM BillingPeriod WHERE BillingPeriodClass_ID = 1 AND CODE = #BP)
SET #startDate = (SELECT EndDate FROM BillingPeriod WHERE BillingPeriodClass_ID = 1 AND CODE = #BP -1 )
SET #startDate = dateadd(minute, 1, #startDate)
SELECT CGS.Description, SUM(CD.Vvalue) AS P_Val, COUNT(CD.VValue) AS P_Rec, DI.Margin
FROM CGS AS CGS
FULL JOIN ChannelParameter AS CP ON CP.ID = CGS.ID
FULL JOIN ChannelData AS CD ON CP.ID = CD.ID
FULL JOIN DataIntegrity AS DI ON DI.CGS_ID_1 = CGS.ID OR DI.CGS_ID_2 = CGS.ID
WHERE --CD.DDate BETWEEN #startDate AND #endDate AND
DI.Priority = #priority
group by CGS.Description, DI.Margin
Click this for Query Result
Please see below:
Channel Data Table
Channel Parameter Table
I have attached pictures as links: also here is what i mean by the table not being normalised properly they both have CGS.ID as a primrary and foreign key but this is actually a primary key in the cgs table the problem is when i try and join the DI table i dont get results from all tables:
DECLARE #bp varchar(4)
DECLARE #priority varchar(2)
DECLARE #startDate datetime
DECLARE #endDate datetime
SET #bp = 1710
SET #priority = 2
SET #endDate = (SELECT EndDate FROM BillingPeriod WHERE BillingPeriodClass_ID = 1 AND CODE = #BP)
SET #startDate = (SELECT EndDate FROM BillingPeriod WHERE BillingPeriodClass_ID = 1 AND CODE = #BP -1 )
SET #startDate = dateadd(minute, 1, #startDate)
SELECT CGS.Description, SUM(CD.Vvalue) AS P_Val, COUNT(CD.VValue) AS P_Rec
FROM CGS AS CGS
FULL JOIN ChannelParameter AS CP ON CP.ID = CGS.ID
FULL JOIN ChannelData AS CD ON CP.ID = CD.ID
WHERE CD.DDate BETWEEN #startDate AND #endDate and CGS.ID = 88
group by CGS.Description
RESULT :
Description P_Val P_Rec
EP 308 12 CONTROL TRF FEEDER NO 1 - Q Exp, 4514.37, 1488
The problem is pretty clear that there is no matched record for CD.DDate BETWEEN #startDate AND #endDate condition. And I suspected that #startDate variable might be null because of returning no record for CODE = #BP -1 condition. So, would you try to change this line;
SET #startDate = (SELECT top 1 EndDate FROM BillingPeriod
WHERE BillingPeriodClass_ID = 1 AND CODE < #BP order by CODE desc)
I have written two queries and I need help to know which one will be better in term of performance. Both do the same thing. Please also advise if you have better a way of writing the query
Query 1
DECLARE #TotalAvailedLateNightGeneral INT
;WITH CTE (TotalDaysAppliedFor) AS (
SELECT SUM(TotalDaysAppliedFor) AS TotalDaysAppliedFor
FROM [CURFEW_RLX_REQUEST] WITH (NOLOCK)
GROUP BY StaffSeqId, RequestTypeId, MONTH(PermissionRequiredFrom), StatusId, IsActive
HAVING StaffSeqId = 41130
AND RequestTypeId = 3
AND MONTH(PermissionRequiredFrom) = MONTH('2016-03-30 00:00:00.000')
AND StatusId <> 111
AND IsActive = 1
)
SELECT #TotalAvailedLateNightGeneral = SUM(TotalDaysAppliedFor)
FROM CTE
SELECT #TotalAvailedLateNightGeneral
QUERY 2
SELECT SUM(TotalDaysAppliedFor) AS TotalDaysAppliedFor
FROM [CURFEW_RLX_REQUEST] WITH (NOLOCK)
--GROUP BY StaffSeqId,RequestTypeId,MONTH(PermissionRequiredFrom),StatusId,IsActive
WHERE StaffSeqId = 41130
AND RequestTypeId = 3
AND MONTH(PermissionRequiredFrom) = MONTH('2016-03-30 00:00:00.000')
AND StatusId <> 111
AND IsActive = 1
DECLARE #StartDate DATETIME = '2016-03-01'
DECLARE #EndDate DATETIME = '2016-04-01'
SELECT TotalDaysAppliedFor = SUM(TotalDaysAppliedFor)
FROM dbo.QAG_GEMS_CURFEW_RLX_REQUEST
WHERE StaffSeqId = 41130
AND RequestTypeId = 3
AND PermissionRequiredFrom >= #StartDate
AND PermissionRequiredFrom < #EndDate
AND StatusId != 111
AND IsActive = 1
I have 2 SQLs,
SELECT #AlreadyPerformedActionsPerDay = COUNT(*)
FROM UserRewardActions URA
INNER JOIN UserRewardActionTypes URAT ON URAT.ID = URA.UserRewardActionTypeID
WHERE URA.UserID = #UserID
AND (
#UserRewardActionTypeID = 1 -- Because the register action is not per-date-wise(only allows once in lifetime)
OR CreationDateInUtc BETWEEN CAST(GETUTCDATE() AS DATE) AND DATEADD(DAY, 1, CAST(GETUTCDATE() AS DATE)) -- Inside Current Date
);
SELECT #AlreadyRedeemedTheCurrentAction = 1
FROM UserRewardActions URA
INNER JOIN UserRewardActionTypes URAT ON URAT.ID = URA.UserRewardActionTypeID
WHERE URA.UserID = #UserID
AND CreationDateInUtc BETWEEN CAST(GETUTCDATE() AS DATE) AND DATEADD(DAY, 1, CAST(GETUTCDATE() AS DATE)) -- Inside Current Date
AND URL IS NOT NULL
AND URL = #Url;
The fist SQL is the grabbing total number of user actions today. Second, is checking whether the current url is already used by the same user. This is fine. But I am looking to merge this query for performance issue.
well, after reformatting your queries as below. I can see that they have different criteria.
DECLARE #from DateTime;
DECLARE #to DateTime;
SET #from = cast(getutcdate() as Date);
SET #to = dateadd(DAY, 1, #from));
SELECT
#AlreadyPerformedActionsPerDay = COUNT(*)
FROM
UserRewardActions URA
JOIN
UserRewardActionTypes URAT
ON URAT.ID = URA.UserRewardActionTypeID
WHERE
URA.UserID = #UserID
AND
(
#UserRewardActionTypeID = 1
OR
CreationDateInUtc BETWEEN #from AND #to
);
SELECT
#AlreadyRedeemedTheCurrentAction = 1
FROM
UserRewardActions URA
JOIN
UserRewardActionTypes URAT
ON URAT.ID = URA.UserRewardActionTypeID
WHERE
URA.UserID = #UserID
AND
CreationDateInUtc BETWEEN #from AND #to
AND
URL IS NOT NULL
AND
URL = #Url;
In the following query, I would like the remove the subquery from the JOIN statement (since my two SELECT statements are selecting data from same table). How can I use that alias? Thanks in advance for any help.
declare #StartDate datetime= '8/01/2011'
declare #EndDate datetime = '9/20/2011'
declare #PortfolioId int = 6
SELECT
Previous.PreviousNAV,
Todays.TodaysNAV,
ISNULL((Todays.TodaysNAV-Previous.PreviousNAV),0) NetChange,
ISNULL((Todays.TodaysNAV-Previous.PreviousNAV) / Todays.TodaysNAV,0) BAMLIndex
FROM
(
SELECT PortfolioId,ISNULL(NAV,0) PreviousNAV
FROM Fireball..NAV
WHERE Date BETWEEN #StartDate AND #EndDate and PortfolioId = #PortfolioId
) Previous
JOIN
(
SELECT PortfolioId,ISNULL(NAV,0) TodaysNAV
FROM Fireball..NAV
WHERE Date = #EndDate and PortfolioId = #PortfolioId
) Todays
ON Previous.PortfolioId = Todays.PortfolioId
Just eliminate the subqueries entirely. I don't think they add anything to the query. Try this instead:
SELECT
Previous.NAV as PreviousNAV,
Todays.NAV as TodaysNav,
ISNULL((Todays.NAV-Previous.NAV),0) NetChange,
ISNULL((Todays.NAV-Previous.NAV) / Todays.NAV,0) BAMLIndex
FROM
Fireball..NAV as Previous
JOIN
Fireball..NAV as Todays
ON Previous.portfolioID = Todays.PortfolioID
WHERE Previous.Date BETWEEN #StartDate AND #EndDate
AND Previous.PortfolioId = #PortfolioId
AND Todays.Date = #EndDate