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'
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 writing a T-SQL query to calculate percentages of orders that have a ship time of over X days.
What I have now works but it feels clunky and I'm always looking to improve my query writing skills.
The first CTE is getting total orders from a time frame. The second CTE is getting any orders that have a ship date that is 3 days older (or less) than the order date.
;WITH TotalOrders
AS (
SELECT COUNT(*) AS TotalOrders
, MONTH(OrderDate) AS Month
, YEAR(OrderDate) AS Year
FROM Orders
WHERE OrderDate >= '2020-05-01'
GROUP BY MONTH(OrderDate), YEAR(OrderDate)
),
Under3
AS (
SELECT COUNT(*) AS Under3Days
, MONTH(OrderDate) AS Month
, YEAR(OrderDate) AS Year
FROM SorMaster SM
WHERE OrderDate >= '2020-05-01'
AND DATEDIFF(D, OrderDate, ShipDate) <= 3
GROUP BY MONTH(OrderDate), YEAR(OrderDate)
)
SELECT ROUND(Under3Days * 100.0 / TPO.TotalOrders, 1) AS 'PercentOfTotal'
, TPO.Month
, TPO.Year
FROM Under3
JOIN TotalOrders TPO
ON TPO.Month = Under3.Month
AND TPO.Year = Under3.Year
I know I can do this in temp tables too but wondering if there's a best practice to follow when doing these calculations
You can use conditional aggregation:
SELECT
ROUND(AVG(CASE WHEN ShipDate <= DATEADD(day, 3, OrderDate) THEN 100.0 ELSE 0 END), 1) AS PercentOfTotal
, MONTH(OrderDate) AS Month
, YEAR(OrderDate) AS Year
FROM Orders
WHERE OrderDate >= '2020-05-01'
GROUP BY MONTH(OrderDate), YEAR(OrderDate)
I'm fairly new to SQL and find this site to be a brilliant resource. I'm hoping for a little bit of help with a task I've been assigned.
Basically I need to find the number of periods of sickness a member of staff has taken in the last 12 month and the duration of each period of sickness.
I have a simple table that looks like this:
Agent Date Status
A 01/07/2015 SHIFT
A 02/07/2015 SHIFT
A 03/07/2015 SICK
A 04/07/2015 SHIFT
A 05/07/2015 SHIFT
A 06/07/2015 SHIFT
B 01/07/2015 SICK
B 02/07/2015 SICK
B 03/07/2015 SHIFT
B 04/07/2015 SHIFT
B 05/07/2015 SICK
B 06/07/2015 SICK
C 01/07/2015 SHIFT
C 02/07/2015 SHIFT
C 03/07/2015 SICK
C 04/07/2015 SICK
C 05/07/2015 SICK
C 06/07/2015 SHIFT
I'm hoping someone can help me find some code that would produce the following kind of output:
Agent Days
A 1
B 2
B 2
C 3
Any help would be greatly appreciated.
Cheers
For sql-server:
select count(1) from TableA
where Status = 'SICK' and Date >= CAST(DATEADD(MONTH, -12, CURRENT_TIMESTAMP) AS DATE)
group by Agent
Grouped by periods of sickness:
WITH Cte AS(
SELECT *,
DATEDIFF(dd, '12/30/1899', [Date]) as [number],
RN = DATEDIFF(dd, '12/30/1899', [Date]) - ROW_NUMBER()
OVER(PARTITION BY Agent ORDER BY DATEDIFF(dd, '12/30/1899', [Date]))
FROM TableA
WHERE
[Status] = 'SICK' and
[Date] >= CAST(DATEADD(MONTH, -12, CURRENT_TIMESTAMP) AS DATE)
)
,CteFinal AS(
SELECT
Agent,
startNumber = MIN(number),
endNumber = MAX(number)
FROM Cte
GROUP BY Agent, RN
)
select Agent, endNumber - startNumber +1 as [Days] from CteFinal
group by agent, startNumber, endNumber
Sqlfiddle
In addition, for case with days off in table TableB:
WITH Cte AS(
SELECT distinct *,
DATEDIFF(dd, '12/30/1899', [Date]) as [number],
RN = DATEDIFF(dd, '12/30/1899', [Date]) - ROW_NUMBER()
OVER(PARTITION BY Agent ORDER BY DATEDIFF(dd, '12/30/1899', [Date]))
FROM (select distinct * from TableA
union all
select distinct Agent, b.Date, 'DAY OFF' from TableA cross join TableB b) TableA
WHERE
[Status] IN ('SICK', 'DAY OFF') and
[Date] >= CAST(DATEADD(MONTH, -12, CURRENT_TIMESTAMP) AS DATE)
)
,CteFinal AS(
SELECT
Agent,
startNumber = MIN(number),
endNumber = MAX(number),
dayOffs = SUM(CASE WHEN [Status] = 'DAY OFF' THEN 1 ELSE 0 END)
FROM Cte
GROUP BY Agent, RN
)
select Agent, endNumber - startNumber +1 - sum(dayOffs) as [Days] from CteFinal
group by agent, startNumber, endNumber
having(endNumber - startNumber +1 - sum(dayOffs) > 0)
Sqlfiddle
I have little table which gives me a very hard time:
Person datetime1 datetime2
Eric 2012-10-01 09:00:05.000 2012-10-01 22:00:00.000
Anna 2012-10-02 06:00:05.000 2012-10-03 12:00:05.000
Richard 2012-10-03 09:00:05.000 2012-10-04 02:00:05.000
Chuck 2012-10-01 12:00:05.000 2012-10-01 23:00:05.000
I am trying to write a query, which gives me statistics table. This table contains information about when a user logged in and out (daily granularity):
Date logged_in logged_off
2012-10-01 2 2
2012-10-02 1 0
2012-10-03 1 1
2012-10-04 0 1
According to my research, a pivot command could solve the problem?
select Person,
SUM(case when datetime1 = '2012-10-01' then 1 else 0 end) as [loggeed_in],
SUM(case when datetime2 = '2012-10-01' then 1 else 0 end) as [logged_of]
from table
group by Person
This is not working... Do you have any ideas?
This will fix the current query, but don't know if it will solve the whole problem...
select Person,
SUM(case when convert(varchar(10), datetime1, 111) = '2012/10/01' then 1 else 0 end) as [loggeed_in],
SUM(case when convert(varchar(10), datetime2, 111) = '2012/10/01' then 1 else 0 end) as [logged_of]
from table
group by Person
EDIT: I believe this will better suit requirements...
SELECT
[Date] = dt,
logged_in = (
SELECT COUNT(*)
FROM table1
WHERE convert(varchar(10), datetime1, 111) = convert(varchar(10), dt, 111)),
logged_off = (
SELECT COUNT(*)
FROM table1
WHERE convert(varchar(10), datetime2, 111) = convert(varchar(10), dt, 111))
FROM (
SELECT TOP 1000
row_number() OVER(ORDER BY (SELECT 0)) AS N
FROM master.dbo.syscolumns sc1, master.dbo.syscolumns sc2) tally
CROSS APPLY(
SELECT dt = DATEADD(dd, tally.N - 1, '2012-10-1')) tallydt
WHERE dt BETWEEN (SELECT MIN(dateadd(dd, -1, datetime1)) FROM table1) AND (SELECT MAX(datetime2) FROM table1)
GROUP BY dt
ORDER BY dt
Here is the working solution:
WITH O AS (
SELECT
CAST([login Date & Time] AS DATE) loginDate
,COUNT(*) logined
FROM table
GROUP BY CAST([login Date & Time] AS DATE)
), C AS (
SELECT
CAST([Close Date & Time] AS DATE) CloseDate
,COUNT(*) Closed
FROM table
WHERE [Close Date & Time] IS NOT NULL
GROUP BY CAST([Close Date & Time] AS DATE)
)
SELECT
COALESCE(C.CloseDate, O.loginDate) TheDate
--,O.loginDate
--,C.CloseDate
,O.logined
,C.Closed
FROM O
FULL JOIN C
ON O.loginDate = C.CloseDate
ORDER BY TheDate
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]