So i have a bunch of data, and i already have it grouped by The column name and month.
Here is the SQL query i have so far
TestName is a column name, POE Business Rules/Submit occur many times per column
VExecutionGlobalHistory is the name of the table,
Im using Microsoft SQL Server Management Studio 2010
select
year(dateadd(mm,datediff(mm,0,StartTime),0)),
datename(month,dateadd(mm,datediff(mm,0,StartTime),0)),TestName,
Case WHEN Testname = 'POE Business Rules' THEN (count(TestName)*36) WHEN TestName = 'Submit' THEN (count(TestName)*6) ELSE 0 END
From VExecutionGlobalHistory
group by
year(dateadd(mm,datediff(mm,0,StartTime),0)),
datename(month,dateadd(mm,datediff(mm,0,StartTime),0)),TestName
This query gives me this format
2013 |APRIL| POE Business Rules| 1044
2013 |APRIL| SUBMIT | 96
2013 |JULY | POE Business Rules| 216
2013 |JULY | SUBMIT | 102
I would like to have a final format where it has only each month with the sum of the counts
2013|APRIL|SUM of the counts or (1044 + 96)
2013|JULY |SUM of the counts or (216 + 102)
I dont need the testname just the sum of the counts per month
I have tried adding SUM right before case but i get
"Cannot perform an aggregate function on an expression containing an aggregate or a subquery." Error.
Any suggestions on another approach?
You could just use a subquery:
SELECT Year_, Month_, SUM(Counts)
FROM (
SELECT YEAR(DATEADD(MM,DATEDIFF(MM,0,StartTime),0))'Year_'
,DATENAME(MONTH,DATEADD(MM,DATEDIFF(MM,0,StartTime),0))'Month_'
,TestName
,CASE WHEN Testname = 'POE Business Rules' THEN (count(TestName)*36)
WHEN TestName = 'Submit' THEN (COUNT(TestName)*6)
ELSE 0
END 'Counts'
FROM VExecutionGlobalHistory
GROUP BY YEAR(DATEADD(MM,DATEDIFF(MM,0,StartTime),0))
,DATENAME(MONTH,DATEADD(MM,DATEDIFF(MM,0,StartTime),0))
,TestName
)sub
GROUP BY Year_, Month_
ORDER BY CAST(CAST(Year_ AS CHAR(4)) + Month_ + '01' AS DATETIME)
Update: Added ORDER BY to sort by YEAR/MONTH oldest first.
Something like
Select SumYear,SomeMonth,Sum(SumCounts) From
(
select
year(dateadd(mm,datediff(mm,0,StartTime),0)) as SumYear,
datename(month,dateadd(mm,datediff(mm,0,StartTime),0)) as SumMonth,TestName,
Case WHEN Testname = 'POE Business Rules' THEN (count(TestName)*36) WHEN TestName = 'Submit' THEN (count(TestName)*6) ELSE 0 END as sumCounts
From VExecutionGlobalHistory
group by
year(dateadd(mm,datediff(mm,0,StartTime),0)),
datename(month,dateadd(mm,datediff(mm,0,StartTime),0)),TestName ) sums
Group by SumYear,SumMonth
should do it
Your logic may be overcomplicated. It sounds like you just want a weighted sum grouped by (year,month). Rows with 'POE Business Rules' are worth 36, rows with 'Submit' are worth 6, and all others are worth 0.
SELECT
YEAR(StartTime),
DATENAME(month,DATEADD(month,MONTH(StartTime)-1,0)),
SUM(
CASE Testname
WHEN 'POE Business Rules' THEN 36
WHEN 'Submit' THEN 6
ELSE 0
END
)
FROM VExecutionGlobalHistory
GROUP BY YEAR(StartTime),MONTH(StartTime)
ORDER BY YEAR(StartTime),MONTH(StartTime)
Related
My data looks like the following
TicketID OwnedbyTeamT Createddate ClosedDate
1234 A
1234 A 01/01/2019 01/05/2019
1234 A 10/05/2018 10/07/2018
1234 B 10/04/2019 10/08/2018
1234 finance 11/01/2018 11/11/2018
1234 B 12/02/2018
Now, I want to calculate the datediff between the closeddates for teams A, and B, if the max closeddate for team A is greater than max closeddate team B. If it is smaller or null I don't want to see them. So, for example,I want to see only one record like this :
TicketID (Datediff)result-days
1234 86
and for another tickets, display the info. For example, if the conditions aren't met then:
TicketID (Datediff)result-days
2456 -1111111
Data sample for 2456:
TicketID OwnedbyTeamT Createddate ClosedDate
2456 A
2456 A 10/01/2019 10/05/2019
2456 B 08/05/2018 08/07/2018
2456 B 06/04/2019 06/08/2018
2456 finance 11/01/2018 11/11/2018
2456 B 12/02/2018
I want to see the difference in days between 01/05/2019 for team A, and
10/08/2018 for team B.
Here is the query that I wrote, however, all I see is -1111111, any help please?:
SELECT A.incidentid,
( CASE
WHEN Max(B.[build validation]) <> 'No data'
AND Max(A.crfs) <> 'No data'
AND Max(B.[build validation]) < Max(A.crfs) THEN
Datediff(day, Max(B.[build validation]), Max(A.crfs))
ELSE -1111111
END ) AS 'Days-CRF-diff'
FROM (SELECT DISTINCT incidentid,
Iif(( ownedbyteam = 'B'
AND titlet LIKE '%Build validation%' ), Cast(
closeddatetimet AS NVARCHAR(255)), 'No data') AS
'Build Validation'
FROM incidentticketspecifics) B
INNER JOIN (SELECT incidentid,
Iif(( ownedbyteamt = 'B'
OR ownedbyteamt =
'Finance' ),
Cast(
closeddatetimet AS NVARCHAR(255)), 'No data') AS
'CRFS'
FROM incidentticketspecifics
GROUP BY incidentid,
ownedbyteamt,
closeddatetimet) CRF
ON A.incidentid = B.incidentid
GROUP BY A.incidentid
I hope the following answer will be of help.
With two subqueries for the two teams (A and B), the max date for every Ticket is brought. A left join between these two tables is performed to have these information in the same row in order to perform DATEDIFF. The last WHERE clause keeps the row with the dates greater for A team than team B.
Please change [YourDB] and [MytableName] in the following code with your names.
--Select the items to be viewed in the final view along with the difference in days
SELECT A.[TicketID],A.[OwnedbyTeamT], A.[Max_DateA],B.[OwnedbyTeamT], B.[Max_DateB], DATEDIFF(dd,B.[Max_DateB],A.[Max_DateA]) AS My_Diff
FROM
(
--The following subquery creates a table A with the max date for every project for team A
SELECT [TicketID]
,[OwnedbyTeamT]
,MAX([ClosedDate]) AS Max_DateA
FROM [YourDB].[dbo].[MytableName]
GROUP BY [TicketID],[OwnedbyTeamT]
HAVING [OwnedbyTeamT]='A')A
--A join between view A and B to bring the max dates for every project
LEFT JOIN (
--The max date for every project for team B
SELECT [TicketID]
,[OwnedbyTeamT]
,MAX([ClosedDate]) AS Max_DateB
FROM [YourDB].[dbo].[MytableName]
GROUP BY [TicketID],[OwnedbyTeamT]
HAVING [OwnedbyTeamT]='B')B
ON A.[TicketID]=B.[TicketID]
--Fill out the rows on the max dates for the teams
WHERE A.Max_DateA>B.Max_DateB
You might be able to do with a PIVOT. I am leaving a working example.
SELECT [TicketID], "A", "B", DATEDIFF(dd,"B","A") AS My_Date_Diff
FROM
(
SELECT [TicketID],[OwnedbyTeamT],MAX([ClosedDate]) AS My_Max
FROM [YourDB].[dbo].[MytableName]
GROUP BY [TicketID],[OwnedbyTeamT]
)Temp
PIVOT
(
MAX(My_Max)
FOR Temp.[OwnedbyTeamT] in ("A","B")
)PIV
WHERE "A">"B"
Your sample query is quite complicated and has conditions not mentioned in the text. It doesn't really help.
I want to calculate the datediff between the closeddates for teams A, and B, if the max closeddate for team A is greater than max closeddate team B. If it is smaller or null I don't want to see them.
I think you want this per TicketId. You can do this using conditional aggregation:
SELECT TicketId,
DATEDIFF(day,
MAX(CASE WHEN OwnedbyTeamT = 'B' THEN ClosedDate END),
MAX(CASE WHEN OwnedbyTeamT = 'A' THEN ClosedDate END) as diff
)
FROM incidentticketspecifics its
GROUP BY TicketId
HAVING MAX(CASE WHEN OwnedbyTeamT = 'A' THEN ClosedDate END) >
MAX(CASE WHEN OwnedbyTeamT = 'B' THEN ClosedDate END)
I am working on a simple query trying to display the total of the totals for 12 periods. I am using a SUM(SUM(value)) function to retrieve the data that I want, however, I am having a hard time displaying a second column in my result.
SELECT CENTRE, SUM(SUM(AMOUNT)) "TOTAL PAY" FROM AB
WHERE ACCOUNT LIKE 'N%' AND CENTRE = '2001' AND YEAR > 2015 GROUP BY AMOUNT, CENTRE;
The error that I am getting has to do with the grouping of the sentence.
Can you please tell me what I have done wrong. I have solved the problem with a sub-query, but I need to fix this query as well because it is used in a more advanced one as a sub-query.
Your questions is too vague to know for sure what you want. For example, what do you mean by "totals for 12 periods"? Is it that for YEAR > 2015 you have 12 rows? Are you always having CENTRE = in your WHERE clause? If so, this might be what you want:
SELECT
MAX(centre) "CENTRE",
SUM(amount) "TOTAL PAY"
FROM
ab
WHERE
account LIKE 'N%'
AND
centre = '2001'
AND
year > 2015;
Or in case CENTRE = 'smth' might not be in your WHERE clause an you need total values for each CENTRE:
SELECT
centre "CENTRE",
SUM(amount) "TOTAL PAY"
FROM
ab
WHERE
account LIKE 'N%'
/* AND
centre = '2001'*/
AND
year > 2015
GROUP BY
centre;
Or in case for every (or one) CENTRE row you need to have total value of all centres:
SELECT
"CENTRE",
total "TOTAL PAY"
FROM
(
SELECT
centre,
ROW_NUMBER() OVER(PARTITION BY
centre
ORDER BY
0
) rn,
SUM(
amount
) OVER(PARTITION BY
0
) total
FROM
ab
WHERE
account LIKE 'N%'
AND
year > 2015
)
WHERE
rn = 1;
Below is my table schema:- Appointments
--------------------------------------
| schID | appointment_date | amount | location |
--------------------------------------
I want to fire a single query where I can get the sum of amount, total appointment_date this year i.e 2016 and remaining appointment_date this year i.e 2016.
So I wrote the below query to calculate the above fields:-
SELECT sum(a.amount) as total,
count(distinct a.appointment_date) as total_appointment,
count(distinct a2.appointment_date) as remaining appointments
from Appointments a
LEFT JOIN Appointments a2 ON a.schID = a2.schID
WHERE a2.appointment_date > GETDATE() AND year(a.appointment_date) = 2016
group by a.location
The above query doesnt return value as per requirement :(
The database belongs to SQL Server.
You can use conditional aggregation for this:
SELECT sum(amount) as total,
count(appointment_date) as total_appointment,
count(DISTINCT CASE
WHEN appointment_date > GETDATE() AND YEAR(appointment_date) = 2016
THEN DATE(appointment_date)
END) as remaining appointments
from Appointments a
group by a.location
You shouldn't need a join for this type of query:
SELECT sum(a.amount) as total, count(a.appointment_date) as total_appointment,
sum(case when a.appointment_date > getdate() then 1 else 0
end) as remaining appointments
from Appointments a
where year(a.appointment_date) = year(GETDATE() );
If you need the breakdown by location, then include location in both the select and group by clauses.
I am using a hosted SQL 2008 database (so can't create tables or modify values) and would like to divide two numbers from the same column to get a single percentage answer. The values are entered into the same column (TA_ANS_ANSWER) but the value entered is based on another field, the question (TA_ANS_QUESTION).
e.g. for this month;
First question - "Total No. Contractors on e-learning User List" - Answer entered '430'.
Second question - "Total No. Contractors on e-learning inducted report" - Answer entered '357'
I need to get the value 83% for the above.
I need to calculate a single percentage value for each Month as the answers get populated.
The query below gives the base query which returns the name of the previous MONTH (e.g. Nov), PPM ID and Answer (e.g. 430). I can modify this to return both rows, 1 for each question answered but I only want a single row with the Month, PPM ID and Percentage calculation.
Apologies if the answer is staring me in the face but any help would be greatly appreciated.
SELECT CONVERT(varchar(3), TA_DUE_DATE-28, 100) AS MONTH,
TA_TASK_ID AS PPM,
F_TASK_ANS.TA_ANS_ANSWER AS ANSWER
FROM F_TASK_ANS
INNER JOIN F_TASKS
ON F_TASK_ANS.TA_ANS_FKEY_TA_SEQ = F_TASKS.TA_SEQ
WHERE TA_ANS_ANSWER <> ''
AND F_TASKS.TA_FKEY_CTR_SEQ = 126
AND F_TASK_ANS.TA_ANS_QUESTION LIKE '%Total No. Contractors on e-learning User List%'
AND (TA_HIST_STATUS IS NULL OR TA_HIST_STATUS = 'COMPLETE')
AND TA_TASK_ID LIKE '%6025'
AND TA_DUE_DATE >= GETDATE()-360
AND TA_DUE_DATE <= GETDATE()+7
ORDER BY PPM
What you are looking for is called a pivot. This can be done with the PIVOT keyword, or it can be done manually with GROUP BY and MIN(CASE WHEN ... END). Check out other answers tagged with "pivot" for more examples.
SELECT CONVERT(varchar(3), TA_DUE_DATE-28, 100) AS MONTH,
TA_TASK_ID AS PPM,
MIN(CASE WHEN F_TASK_ANS.TA_ANS_QUESTION LIKE '%Total No. Contractors on e-learning inducted report%' THEN F_TASK_ANS.TA_ANS_ANSWER END) +0.0
/ MIN(CASE WHEN F_TASK_ANS.TA_ANS_QUESTION LIKE '%Total No. Contractors on e-learning User List%' THEN F_TASK_ANS.TA_ANS_ANSWER END)
AS PERCENTAGE
FROM F_TASK_ANS
INNER JOIN F_TASKS
ON F_TASK_ANS.TA_ANS_FKEY_TA_SEQ = F_TASKS.TA_SEQ
WHERE TA_ANS_ANSWER <> ''
AND F_TASKS.TA_FKEY_CTR_SEQ = 126
AND (F_TASK_ANS.TA_ANS_QUESTION LIKE '%Total No. Contractors on e-learning User List%' OR
(F_TASK_ANS.TA_ANS_QUESTION LIKE '%Total No. Contractors on e-learning inducted report%')
AND (TA_HIST_STATUS IS NULL OR TA_HIST_STATUS = 'COMPLETE')
AND TA_TASK_ID LIKE '%6025'
AND TA_DUE_DATE >= GETDATE()-360
AND TA_DUE_DATE <= GETDATE()+7
GROUP BY CONVERT(varchar(3), TA_DUE_DATE-28, 100),TA_TASK_ID
One possible answer is to use a Common Table Expression (CTE). Something like this:
;with TotalOnELearningList (Month, TaskID, NumberOnList) as
(
select
convert(varchar(3), ta_due_date - 28, 100) as month,
ta_task_id,
f_task_ans.ta_ans_answer
from ...
),
TotalOnInductedReport (Month, TaskID, NumberInductedReport) as
(
...
),
select
case NumberInductedReport when 0 then 0 else NumberOnList / NumberInductedReport * 100 end as 'Percent',
...
from TotalOnELearningList
inner join TotalOnIndutedReport
on...
I'd like to be able to rollup the count of commitments to a product over years -
The data for new commitments in each year looks like this:
Year | Count of new commitments | (What I'd like - count of new commitments to date)
1986 4 4
1987 22 26
1988 14 40
1989 1 41
I know that within a year you can do year to date, month to date etc, but I need to do it over multiple years.
the mdx that gives me the first 2 columns is (really simple - but I don't know where to go from here):
select [Measures].[Commitment Count] on 0
, [Date Dim].[CY Hierarchy].[Calendar Year] on 1
from [Cube]
Any help would be great
In MDX something along the line:
with member [x] as sum(
[Date Dim].[CY Hierarchy].[Calendar Year].members(0) : [Date Dim].[CY Hierarchy].currentMember,
[Measures].[Commitment Count]
)
select [x] on 0, [Date Dim].[CY Hierarchy].[Calendar Year] on 1 from [Cube]
Use a common table expression:
with sums (year,sumThisYear,cumulativeSum)
as (
select year
, sum(commitments) as sumThisYear
, sum(commitments) as cumulativeSum
from theTable
where year = (select min(year) from theTable)
group by year
union all
select child.year
, sum(child.commitments) as sumThisYear
, sum(child.commitments) + parent.cumulativeSum as cumulativeSum
from sums par
JOIN thetable Child on par.year = child.year - 1
group by child.year,parent.cumulativeSum
)
select * from sums
There's a bit of a "trick" in there grouping on parent.cumulativeSum. We know that this will be the same value for all rows, and we need to add it to sum(child.commitments), so we group on it so SQL Server will let us refer to it. That can probably be cleaned up to remove what might be called a "smell", but it will work.
Warning: 11:15pm where I am, written off the top of my head, may need a tweak or two.
EDIT: forgot the group by in the anchor clause, added that in