Hi I am trying to duplicate a complex IIF function I used in MS Access but can't seem to translating it into a SLQ 2008 using CASE. I am trying to create a WHERE clause something like this
.....
WHERE
(IIF([Created Date]= NULL, IIF(DATEDIFF(day,[Created Date],[POSTED Date])<=3,1,IIF([Created Date] BETWEEN [Disti Reported Sales Date] AND [Posted Date]),1,NULL)))=1
AND
......
Basically what its doing is looking at a date from one column and comparing it to two other columns but if one of the columns is NULL then it uses a different comparison.
The literal translation should look close to this:
WHERE (CASE
WHEN [Created Date] IS NULL
THEN (CASE
WHEN DATEDIFF(DD, [Created Date], [POSTED Date]) <= 3
THEN 1
ELSE (CASE
WHEN [Created Date] BETWEEN [Disti Reported Sales Date] AND [Posted Date]
THEN 1
ELSE 0
END)
END)
ELSE 0
END) = 1
However, this can be simplified to something like this:
WHERE (CASE
WHEN [Created Date] IS NULL AND DATEDIFF(DD, [Created Date], [POSTED Date]) <= 3 THEN 1
WHEN [Created Date] IS NULL AND [Created Date] BETWEEN [Disti Reported Sales Date] AND [Posted Date] THEN 1
ELSE 0 END) = 1
As noted in my comment, it still seems odd that if [Created Date] IS NULL, you are trying to still use it in any calculation.
Related
I have a SQL query as shown below. I would like to get the correct document count based on minutes different from the assigned date vs the current date, but I noticed the query will not count the correct Document No.
SELECT
COUNT(CASE
WHEN DATEDIFF(MINUTE, [Assigned Date], GETDATE()) > 60
THEN [Document No.]
ELSE 0
END) AS [Yet to Pick > 1 hour],
COUNT(CASE
WHEN DATEDIFF(MINUTE, [Assigned Date], GETDATE()) > 120
THEN [Document No.]
ELSE 0
END) AS [Yet to Pick > 2 hours]
FROM
tb_name
WHERE
([Shipment] LIKE '%AIR%' OR [Shipment] LIKE '%COURIER%')
Below is my table, the above SQL query result will always return as 2, by right it should return as 1, please advise if there is anything wrong? Let's say current date is 2022-05-27 9:20:00
Document No.
Assigned Date
Shipment
4242423
2022-05-27 10:20:33
AIR
5675756
2022-06-27 18:20:33
AIR
If I understand correctly you Need to change the logic in the case statement when considering only 1 hour time difference
SELECT
COUNT(CASE
WHEN DATEDIFF(MINUTE, [Assigned Date], GETDATE()) >= 60
AND DATEDIFF(MINUTE, [Assigned Date], GETDATE()) < 120
THEN [Document No.]
ELSE NULL
END) AS [Yet to Pick > 1 hour],
COUNT(CASE
WHEN DATEDIFF(MINUTE, [Assigned Date], GETDATE()) >= 120
THEN [Document No.]
ELSE NULL
END) AS [Yet to Pick > 2 hours]
FROM tb_name
WHERE ([Shipment] LIKE '%AIR%' OR [Shipment] LIKE '%COURIER%')
count will count all non-null values, so for else return NULL instead of zero. Plus, maybe the datediff sequence might need swapping the datetime values as you may be producing negative values, but this is data dependent so I am not certain on this latter point.
SELECT
COUNT(CASE
WHEN DATEDIFF(MINUTE, GETDATE(),[Assigned Date]) > 60
THEN [Document No.]
ELSE NULL
END) AS [Yet to Pick > 1 hour],
COUNT(CASE
WHEN DATEDIFF(MINUTE, GETDATE(), [Assigned Date]) > 120
THEN [Document No.]
ELSE NULL
END) AS [Yet to Pick > 2 hours]
--, getdate() timenow
FROM
tb_name
WHERE
([Shipment] LIKE '%AIR%' OR [Shipment] LIKE '%COURIER%')
nb: when I tested getdate() returned 2022-06-27 05:16:53.047
I'm getting the following error:
Msg 102, Level 15, State 1, Line 2
Incorrect syntax near '('.
When executing this query:
SELECT
'Average Total Comp' AS AverageTotalComp,
[2016], [2015], [2014]
FROM
(SELECT
DATEPART(yyyy, [Fiscal Year End Date]),
[Total Compensation ($)]
FROM
dbo.MDexec e) AS SourceTable
PIVOT
(AVG([Total Compensation ($)])
FOR DATEPART(yyyy, [Fiscal Year End Date])
IN ([2016], [2015], [2014])) AS PivotTable;
I attempted to use both YEAR and DATEPART. The error is referencing the opening parentheses on the second DATEPART.
You need to assign an alias to the datepart expression and use that in your pivot clause:
SELECT 'Average Total Comp' AS AverageTotalComp,
[2016], [2015], [2014]
FROM (SELECT datepart(yyyy,[Fiscal Year End Date]) AS dp,
[Total Compensation ($)] FROM dbo.MDexec e)
AS SourceTable
PIVOT (
avg([Total Compensation ($)])
FOR dp
IN ([2016], [2015], [2014])) AS PivotTable;
You don't need Pivot to do this. Try this way
SELECT AverageTotalComp = 'Average Total Comp',
[2016] = Avg(case when year([Fiscal Year End Date]) = 2016 then [Total Compensation ($)] end),
[2017] = Avg(case when year([Fiscal Year End Date]) = 2017 then [Total Compensation ($)] end),
[2018] = Avg(case when year([Fiscal Year End Date]) = 2018 then [Total Compensation ($)] end)
FROM dbo.MDexec e
Where [Fiscal Year End Date] >= '2015-01-01'
and [Fiscal Year End Date] < '2019-01-01'
I have two date columns, [START DATE] and [END DATE] and I want to only insert records whose dates are not in either column. This is what my logic looks like:
MERGE TABLE_A AS Target
USING (SELECT DISTINCT * FROM TABLE_B) AS Source
ON (SELECT Target.[START DATE] + Target.[END DATE] AS Target.[COMPAREDATE] =
SELECT Source.[START DATE] + Source.[END DATE] AS Source.[COMPAREDATE])
WHEN NOT MATCHED THEN
INSERT ([DATE ADDED], [END DATE], ...)
VALUES (Source.[DATE ADDED], Source.[END DATE], ...);
I also tried the code below but it continued to insert duplicates:
ON (Target.[START DATE] = Source.[START DATE] AND Target.[END DATE] = Source.[END DATE])
I'd appreciate any help, thanks!
This code was close:
ON (Target.[START DATE] = Source.[START DATE] AND Target.[END DATE] = Source.[END DATE])
It says, "if both the StartDate and the EndDate match, then the rows match".
If you want to say "if either the StartDates match or the EndDates match, then the rows match", then you should do this:
ON (Target.[START DATE] = Source.[START DATE] OR Target.[END DATE] = Source.[END DATE])
here is my table structure
create table DailyFinishJobsHistory
(
RowID INT NOT NULL IDENTITY (1, 1),
[Job Type] Varchar(16) NOT NULL,
[No of Jobs] INT NOT NULL DEFAULT ((0)),
[Turnaround Time] DECIMAL(10,2) NOT NULL DEFAULT ((0)),
[One Day Per] DECIMAL(8,2),
CreatedDate datetime DEFAULT (GetDate())
)
this way data is stored in table screen shot
now i have to show the data this way & order by date asc and where clause will be there where i need to specify two date.
date OUR_No of jobs OUR_Turnaround_time OUR_One day per Salesnew_ of jobs Salesnew_no of jobs Salesnew_turnaround_time this way i need to show...
i guess i need to use pivot but whatever i tried did not work. so any help will be appreciated. thanks
Your question and requirements are not very clear but I am going to take a guess that you want the following:
select
convert(varchar(10), createddate, 120) date,
sum(case when [job type] = 'OUR' then [No of Jobs] else 0 end) OurNoOfJobs,
sum(case when [job type] = 'OUR' then [Turnaround Time] else 0 end) OurTurnaroundTime,
sum(case when [job type] = 'OUR' then [One Day Per] else 0 end) OurOneDayPer,
sum(case when [job type] = 'SALESNEW' then [No of Jobs] else 0 end) SalesNewNoOfJobs,
sum(case when [job type] = 'SALESNEW' then [Turnaround Time] else 0 end) SalesNewTurnaroundTime,
sum(case when [job type] = 'SALESNEW' then [One Day Per] else 0 end) SalesNewOneDayPer
from DailyFinishJobsHistory
group by convert(varchar(10), createddate, 120);
See SQL Fiddle with Demo.
This uses an aggregate function and a CASE expression to convert and your rows of data into columns using the sum function to aggregate the values the in columns that you want.
I have a SSRS report that needs to switch between three different datasets i.e. order types = Consumable, Service and Total.
I have two queries one for Consumable and one for Service as shown below. I tried putting a union between them but it doesn't seem to be totalling the results i.e. adding the two together. How can I do this?
SELECT COUNT(orderheader.orderid) AS [Consumable Order Amount],
CONVERT(DATE, orderheader.datecreated) AS [Date],
CASE
WHEN orderheader.webref = '' THEN 'Call Centre'
ELSE 'Web'
END AS [Order Type]
FROM orderheader
WHERE CONVERT(DATE, orderheader.datecreated) >= '21 February 2011'
AND CONVERT(DATE, orderheader.datecreated) <= '20 March 2011'
GROUP BY CONVERT(DATE, orderheader.datecreated),
CASE
WHEN orderheader.webref = '' THEN 'Call Centre'
ELSE 'Web'
END
SELECT COUNT(serviceid) AS [Service Order Amount],
CONVERT(DATE, datecreated) AS [Date],
CASE
WHEN serviceorder.webref = '' THEN 'Call Centre'
ELSE 'Web'
END AS SOURCE
FROM serviceorder
WHERE ( CONVERT(DATE, datecreated) >= '21 February 2011' )
AND ( CONVERT(DATE, datecreated) <= '20 March 2011' )
GROUP BY CONVERT(DATE, datecreated),
CASE
WHEN serviceorder.webref = '' THEN 'Call Centre'
ELSE 'Web'
END
ORDER BY [Date]
Can you try something like this for the combined dataset?
;WITH Combined AS
(
SELECT orderid AS id,
datecreated as [datecreated],
webref as [webref]
FROM orderheader
UNION ALL
SELECT serviceid AS id,
datecreated as [datecreated],
webref as [webref]
FROM serviceorder
)
SELECT COUNT(id) AS [Service Order Amount],
CONVERT(DATE, datecreated) AS [Date],
CASE
WHEN webref = '' THEN 'Call Centre'
ELSE 'Web'
END AS SOURCE
FROM Combined
WHERE ( CONVERT(DATE, datecreated) >= '21 February 2011' )
AND ( CONVERT(DATE, datecreated) <= '20 March 2011' )
GROUP BY CONVERT(DATE, datecreated),
CASE
WHEN webref = '' THEN 'Call Centre'
ELSE 'Web'
END
ORDER BY [Date]