CROSS Join is not working in SQL Server - sql

see the output which i am trying to generate by SQL with dummy data
this is my sql which is throwing error Incorrect syntax near the keyword 'GROUP'.
DECLARE #t TABLE(
CallStar datetime,
Direction char(1),
PartyName varchar(100))
INSERT INTO #t VALUES
('20150609 08:02:51','I','VM Channel 1'),
('20150609 08:04:14','I','VM Channel 1'),
('20150609 08:35:51','O','VM Channel 1'),
('20150609 08:40:14','O','VM Channel 1'),
('20150609 08:02:51','I','VM Channel 2'),
('20150609 08:04:14','I','VM Channel 2'),
('20150609 08:35:51','O','VM Channel 2'),
('20150609 08:40:14','O','VM Channel 2'),
('20150609 08:04:14','O','ACC'),
('20150609 08:04:14','I','ACC'),
('20150609 08:04:14','I','ACC')
DECLARE #StartTime datetime = '2015-06-09 09:00:00',
#EndTime datetime = '2015-06-09 18:00:00',
#Interval int = 30 -- this can be changed.
;WITH cSequence AS
(
SELECT
#StartTime AS StartRange,
DATEADD(MINUTE, #Interval, #StartTime) AS EndRange
UNION ALL
SELECT
EndRange,
DATEADD(MINUTE, #Interval, EndRange)
FROM cSequence
WHERE DATEADD(MINUTE, #Interval, EndRange) < #EndTime
)
SELECT
PartyName,
DATEADD(minute, DATEDIFF(minute,0,CallStar) / 30 * 30, 0) AS "DateStart",
DATEADD(minute, 30, DATEADD(minute, DATEDIFF(minute, 0, CallStar) / 30 * 30, 0)) AS "DateEnd",
SUM(CASE WHEN Direction = 'I' THEN 1 ELSE 0 END) AS "Incoming",
SUM(CASE WHEN Direction = 'O' THEN 1 ELSE 0 END) AS "Outgoing",
SUM(CASE WHEN Direction = 'T' THEN 1 ELSE 0 END) AS "Transfer"
FROM #t CROSS JOIN (SELECT * FROM cSequence) s
GROUP BY
PartyName,
DATEADD(minute, DATEDIFF(minute,0,CallStar) / 30 * 30, 0)
ORDER BY
PartyName,
DATEADD(minute, DATEDIFF(minute,0,CallStar) / 30 * 30, 0)
where i am making the mistake for which cross join is not applying?
EDIT 1
For Incoming data calculation
where direction='I' and
Is_Internal=0 and continuation=0 and
RIGHT(convert(varchar,[call duration]),8)<> '00:00:00'
For outgoing data calculation
where direction='O'
and Is_Internal=0 and continuation=0
For outgoing data calculation
where continuation=1
and RIGHT(convert(varchar,[call duration]),8)<> '00:00:00'
For misscall data calculation
where direction='I' and
RIGHT(convert(varchar,[call duration]),8)= '00:00:00' and [Ring duration]>0
just see and tell me can i add more clause here as below
SUM(CASE WHEN (Direction = 'I' AND Is_Internal=0 AND continuation=0 AND
RIGHT(convert(varchar,[call duration]),8)<> '00:00:00') THEN 1 ELSE 0 END) AS "Incoming",
SUM(CASE WHEN (Direction = 'O' AND Is_Internal=0 AND continuation=0
) THEN 1 ELSE 0 END) AS "Outgoing"
EDIT 2
DECLARE #t TABLE(CallStar datetime, Direction char(1), PartyName varchar(100))
INSERT INTO #t VALUES
('2015-06-09 08:02:51','I','VM Channel 1'),
('2015-06-09 08:04:14','I','VM Channel 1'),
('2015-06-09 08:02:51','O','VM Channel 1'),
('2015-06-09 08:02:51','I','VM Channel 1'),
('2015-06-09 08:34:14','I','VM Channel 1'),
('2015-06-09 18:02:51','I','VM Channel 1'),
('2015-06-09 18:04:14','I','VM Channel 1'),
('2015-06-09 18:02:51','O','VM Channel 1'),
('2015-06-09 18:02:51','T','VM Channel 1'),
('2015-06-09 01:02:51','I','VM Channel 2'),
('2015-06-09 02:04:14','I','VM Channel 2'),
('2015-06-09 03:02:51','O','VM Channel 2'),
('2015-06-09 04:02:51','I','VM Channel 2'),
('2015-06-09 05:34:14','I','VM Channel 2'),
('2015-06-09 16:02:51','I','VM Channel 2'),
('2015-06-09 17:04:14','I','VM Channel 2'),
('2015-06-09 18:02:51','O','VM Channel 2'),
('2015-06-09 19:02:51','T','VM Channel 2')
;WITH times AS (
SELECT CAST('1900-01-01 00:00:00.000' AS DATETIME) AS time, 0 AS sortSeq
UNION ALL
SELECT DATEADD(MINUTE,30,time) AS time, sortSeq + 1 AS sortSeq
FROM times
WHERE CAST(DATEADD(MINUTE,30,time) AS DATE) = CAST(time AS DATE)
),
final AS (
SELECT PartyName, DateStar, LEFT(CONVERT(VARCHAR,DATEADD(minute, DATEDIFF(minute,0,time) / 30 * 30, 0),108),5)
+ ' - ' + LEFT(CONVERT(VARCHAR,DATEADD(minute, 30, DATEADD(minute, DATEDIFF(minute, 0, time) / 30 * 30, 0)),108),5) AS groupName, sortSeq
FROM times
CROSS APPLY (SELECT DISTINCT PartyName, CAST(callStar AS DATE) AS dateStar
FROM #t
) a
)
SELECT f.PartyName, f.DateStar, f.GroupName, COALESCE(t.Incoming,0) AS Incoming, COALESCE(t.Outgoing,0) AS Outgoing, COALESCE(t.Transfer,0) AS Transfer
FROM final f
LEFT OUTER JOIN (
SELECT PartyName, CAST(CallStar AS DATE) AS DateStar,
LEFT(CONVERT(VARCHAR,DATEADD(minute, DATEDIFF(minute,0,CallStar) / 30 * 30, 0),108),5)
+ ' - ' + LEFT(CONVERT(VARCHAR,DATEADD(minute, 30, DATEADD(minute, DATEDIFF(minute, 0, CallStar) / 30 * 30, 0)),108),5) AS groupName,
DATEADD(minute, DATEDIFF(minute,0,CallStar) / 30 * 30, 0) AS DateStart,
DATEADD(minute, 30, DATEADD(minute, DATEDIFF(minute, 0, CallStar) / 30 * 30, 0)) AS DateEnd,
SUM(CASE WHEN Direction = 'I' THEN 1 ELSE 0 END) AS Incoming,
SUM(CASE WHEN Direction = 'O' THEN 1 ELSE 0 END) AS Outgoing,
SUM(CASE WHEN Direction = 'T' THEN 1 ELSE 0 END) AS Transfer
FROM #t t
GROUP BY PartyName, CAST(CallStar AS DATE), DATEADD(minute, DATEDIFF(minute,0,CallStar) / 30 * 30, 0)
) t
ON f.PartyName = t.PartyName
AND f.groupName = t.groupName
AND f.dateStar = t.dateStar
ORDER BY f.PartyName, f.DateStar, f.sortSeq

If you want all time slots for all parties you need to do a cross join on the ranges and parties, and then use a left join to fill in the actual data.
I think this is what you want:
with cSequence as (
....
)
SELECT
s.StartRange, s.EndRange,
s.PartyName,
SUM(CASE WHEN Direction = 'I' THEN 1 ELSE 0 END) AS "Incoming",
SUM(CASE WHEN Direction = 'O' THEN 1 ELSE 0 END) AS "Outgoing",
SUM(CASE WHEN Direction = 'T' THEN 1 ELSE 0 END) AS "Transfer"
-- this is what changed
FROM (SELECT * FROM cSequence CROSS JOIN (SELECT DISTINCT PARTYNAME FROM #T) p) S
LEFT JOIN #t t ON s.StartRange = DATEADD(minute, DATEDIFF(minute,0,CallStar) / 30 * 30, 0)
AND s.EndRange = DATEADD(minute, 30, DATEADD(minute, DATEDIFF(minute, 0, CallStar) / 30 * 30, 0))
AND t.PartyName = s.PartyName
GROUP BY
s.PartyName,
s.StartRange,s.EndRange,
DATEADD(minute, DATEDIFF(minute,0,CallStar) / 30 * 30, 0)
ORDER BY
s.PartyName,
s.StartRange,s.EndRange,
DATEADD(minute, DATEDIFF(minute,0,CallStar) / 30 * 30, 0)
;
Sample SQL Fiddle
I left out the temp table and cte and only included the last select.
The query can most likely be improved a bit, but I'll leave that to you.

When you have two or more tables with the same structure
you could select the data this way:
Select * from
(
Select Col_1,Col_2,Col_3 from Table_1 WHERE xxxx
UNION
Select Col_1,Col_2,Col_3 from Table_2 WHERE xxxx
UNION
Select Col_1,Col_2,Col_3 from Table_3 WHERE xxxx
) as NewTable
if you hate JOIN syntax

Below is the code I ended up using. It's based on the SQL from jpw's answer (slightly adapted, as jpw's SQL did not return the data properly).
DECLARE #StartTime DATETIME, #EndTime DATETIME
SELECT #StartTime = '09:00:00'
SELECT #EndTime = '17:30:00'
;WITH times AS (
SELECT CAST(#StartTime AS DATETIME) AS time, 0 AS sortSeq
UNION ALL
SELECT DATEADD(MINUTE,30,time) AS time, sortSeq + 1 AS sortSeq
FROM times
WHERE time < #EndTime
)
, final AS (
SELECT Party1Name, DateStar,
LEFT(CONVERT(VARCHAR,DATEADD(minute, DATEDIFF(minute,0,time) / 30 * 30, 0),108),5) + ' - '
+ LEFT(CONVERT(VARCHAR,DATEADD(minute, 30, DATEADD(minute, DATEDIFF(minute, 0, time) / 30 * 30, 0)),108),5) AS groupName,
sortSeq FROM times
CROSS APPLY (SELECT DISTINCT Party1Name, CAST([call Start] AS DATE) AS dateStar
FROM CSRPhoneData_Interval
) a
)
SELECT f.Party1Name as [CSR Name], f.GroupName as Time, COALESCE(t.Incoming,0) AS Incoming,
COALESCE(t.Outgoing,0) AS OutGoing, COALESCE(t.Transfer,0) AS [Call Transfer],COALESCE(t.misscall,0) AS MissCall
FROM final f
LEFT OUTER JOIN (
SELECT Party1Name, CAST([call Start] AS DATE) AS DateStar,
LEFT(CONVERT(VARCHAR,DATEADD(minute, DATEDIFF(minute,0,[call Start]) / 30 * 30, 0),108),5) + ' - '
+ LEFT(CONVERT(VARCHAR,DATEADD(minute, 30, DATEADD(minute, DATEDIFF(minute, 0, [call Start]) / 30 * 30, 0)),108),5) AS groupName,
DATEADD(minute, DATEDIFF(minute,0,[call Start]) / 30 * 30, 0) AS DateStart,
DATEADD(minute, 30, DATEADD(minute, DATEDIFF(minute, 0, [call Start]) / 30 * 30, 0)) AS DateEnd,
SUM(CASE WHEN (Direction = 'I'
AND Is_Internal=0
AND continuation=0
AND RIGHT(convert(varchar,[call duration]),8)<> '00:00:00') THEN 1 ELSE 0 END) AS Incoming,
SUM(CASE WHEN (Direction = 'O' AND Is_Internal=0 and continuation=0) THEN 1 ELSE 0 END) AS Outgoing,
SUM(CASE WHEN (Direction = 'T'
AND continuation=1
AND RIGHT(convert(varchar,[call duration]),8)<> '00:00:00') THEN 1 ELSE 0 END) AS Transfer,
SUM(CASE WHEN (Direction = 'I'
AND RIGHT(convert(varchar,[call duration]),8)= '00:00:00'
AND [Ring duration]>0) THEN 1 ELSE 0 END) AS misscall
FROM CSRPhoneData_Interval t
GROUP BY Party1Name, CAST([call Start] AS DATE), DATEADD(minute, DATEDIFF(minute,0,[call Start]) / 30 * 30, 0)
) t
ON f.Party1Name = t.Party1Name
AND f.groupName = t.groupName
AND f.dateStar = t.dateStar
ORDER BY f.Party1Name, f.DateStar, f.sortSeq

Related

Error message: Maximum Recursion exhausted even with OPTION( MAXRECURSION 0)

I'm creating a function that will have as input a start date and a number of minutes. The function will add the number of minutes to the start date and it will output an end date, but only considering work hours and excluding weekends and holidays.
You can see part of the function below.
ALTER FUNCTION [dbo].[DataFimPrevisto] (#tempoPrevisto real, #DataIni datetime)
RETURNS datetime
WITH EXECUTE AS CALLER
AS
BEGIN
DECLARE #DataFim datetime;
DECLARE #calculo TABLE( xend datetime, [minutes] int);
WITH
drange (date_start, date_end) AS
(
SELECT
CAST(#DataIni AS DATE) AS date_start,
CAST(DATEADD( YEAR, 1, #DataIni) AS DATE) AS date_end
),
dates0 (adate, date_end) AS
(
SELECT date_start, date_end FROM drange
UNION ALL
SELECT DATEADD(day, 1, adate), date_end FROM dates0 WHERE adate < date_end
),
dates (adate) AS
(
SELECT adate FROM dates0
WHERE DATEPART(dw , adate) NOT IN ('1', '7') AND NOT EXISTS( SELECT 1 FROM BAS_PeriodosExcecoes B WHERE B.Trabalhavel = 0 AND B.DataInicio = adate)
),
hours (hour_start, hour_end) AS
(
SELECT 8.5*60, 12.5*60
UNION
SELECT 13.5*60, 18*60
),
hours_friday (hour_start, hour_end) AS
(
SELECT 8*60, 14*60
),
datehours (xstart, xend) AS
(
SELECT *
FROM
(
SELECT
DATEADD(minute, hour_start, CAST(adate AS datetime)) xstart,
DATEADD(minute, hour_end , CAST(adate AS datetime)) xend
FROM dates AS d, hours AS h
WHERE DATEPART(dw , adate) <> '6'
UNION
SELECT T2.xstart, T2.xend
FROM
(
SELECT *, ROW_NUMBER() OVER(PARTITION BY T.xstart ORDER BY T.xend ASC) AS rank
FROM
(
SELECT
#DataIni xstart,
DATEADD(minute, hour_end, CAST(adate AS datetime)) xend
FROM dates AS d, hours AS h
WHERE adate = CAST( #DataIni AS DATE) AND DATEADD(minute, hour_end, CAST(adate AS datetime)) > #DataIni AND DATEPART(dw , adate) <> '6'
) T
) T2
WHERE T2.rank = 1
UNION
SELECT
DATEADD(minute, hour_start, CAST(adate AS datetime)) xstart,
DATEADD(minute, hour_end , CAST(adate AS datetime)) xend
FROM dates AS d, hours_friday AS h
WHERE DATEPART(dw , adate) = '6'
UNION
SELECT T2.xstart, T2.xend
FROM
(
SELECT *, ROW_NUMBER() OVER(PARTITION BY T.xstart ORDER BY T.xend ASC) AS rank
FROM
(
SELECT
#DataIni xstart,
DATEADD(minute, hour_end, CAST(adate AS datetime)) xend
FROM dates AS d, hours_friday AS h
WHERE adate = CAST( #DataIni AS DATE) AND DATEADD(minute, hour_end, CAST(adate AS datetime)) > #DataIni AND DATEPART(dw , adate) = '6'
) T
) T2
WHERE T2.rank = 1
) T3 WHERE T3.xstart >= #DataIni
),
cumulative (xend, [minutes]) AS
(
SELECT t.xend, SUM(DATEDIFF(MINUTE, xstart, xend)) OVER (ORDER BY xstart) AS [minutes]
FROM datehours AS t
)
INSERT INTO #calculo
SELECT TOP 1 xend, [minutes]
FROM cumulative
WHERE [minutes] >= #tempoPrevisto
ORDER BY cumulative.xend ASC;
SET #DataFim = (SELECT DATEADD( MINUTE, #tempoPrevisto - MAX([minutes]), MAX( [xend])) FROM #calculo);
RETURN(#DataFim);
END;
When I execute this function with
SELECT dbo.DataFimPrevisto( 21240, DATETIMEFROMPARTS( 2023, 1, 25, 6, 0, 0, 0)) OPTION(MAXRECURSION 0);
SSMS returns the error message
The maximum recursion 100 has been exhausted before statement completion
Even tho I'm using OPTION(MAXRECURSION 0).

SQL Server : group by calculated column

I have a table with columns like this:
I want to know the average compliance rate for every question for that period.
I am passing start dates and end dates as parameters to query.
So if I want for two periods I am passing #StartDate (e.g. 1/6/17) and #EndDate (e.g. 30/6/17) for first period and #StartDate2 (1/10/17) and #EndDate2 (31/10/17) for second period.
My SQL query is:
;WITH tmpTab AS
(
SELECT
question,
SUM((CASE WHEN AnswerValue = 1 THEN 1 ELSE 0 END)) Met,
SUM((CASE WHEN AnswerValue = 3 THEN 1 ELSE 0 END)) NA,
SUM((CASE WHEN (ISNULL(AnswerValue,3) <> 3) THEN 1 ELSE 0 END)) MetNotMet,
DATENAME(DAY, #StartDate) + ' ' + DATENAME(MONTH, #StartDate) + ' ' +
DATENAME(YEAR, #StartDate) + ' To ' + DATENAME(DAY,#EndDate) + ' ' +
DATENAME(MONTH, #EndDate) + ' ' + DATENAME(YEAR, #EndDate) AS RepMonthAndYear
FROM
tableA
WHERE
startdate >= #StartDate AND endate <= #EndDate
GROUP BY
Question
UNION ALL
SELECT
question,
SUM((CASE WHEN AnswerValue = 1 THEN 1 ELSE 0 END)) Met,
SUM((CASE WHEN AnswerValue = 3 THEN 1 ELSE 0 END)) NA,
SUM((CASE WHEN (ISNULL(AnswerValue,3) <> 3) THEN 1 ELSE 0 END)) MetNotMet,
DATENAME(DAY,#StartDate2)+' '+DATENAME(MONTH,#StartDate2)+' '+DATENAME(YEAR,#StartDate2)+ ' To ' + DATENAME(DAY,#EndDate2)+' '+DATENAME(MONTH,#EndDate2)+' '+DATENAME(YEAR,#EndDate2) AS RepMonthAndYear
FROM
tableA
WHERE
startdate >= #StartDate2 AND endate <= #EndDate2
GROUP BY
Question
)
SELECT
Question, Met, NA, MetNotMet,
CASE WHEN (Met) = 0 THEN 0 ELSE ROUND(((CONVERT(FLOAT,(Met))/(MetNotMet))* 100),4) END as CompRate
FROM
tmpTab
In this SQL query, I need to group by RepMonthAndYear column also which I can not do as it is a calculated column. I get an error "invalid column".
And if I use this GROUP BY clause:
(DATENAME(DAY,#StartDate2)+' '+DATENAME(MONTH,#StartDate2)+' '+DATENAME(YEAR,#StartDate2)+ ' To ' + DATENAME(DAY,#EndDate2)+' '+DATENAME(MONTH,#EndDate2)+' '+DATENAME(YEAR,#EndDate2) )
I get this error:
Each GROUP BY expression must contain at least one column that is not an outer reference.
How can I solve this problem?
Is there any other way to know average rate group by particular periods?
Given the following Test Data and your SQL I get what you discibe.
CREATE TABLE tableA (
question VARCHAR(50),
AnswerValue INT,
startdate DATE,
endate DATE
);
INSERT INTO tableA VALUES ('Question A', 1, '2017-06-25', '2017-06-26');
INSERT INTO tableA VALUES ('Question A', 1, '2017-06-27', '2017-06-27');
INSERT INTO tableA VALUES ('Question A', 2, '2017-06-27', '2017-06-27');
INSERT INTO tableA VALUES ('Question B', 1, '2017-06-11', '2017-06-12');
INSERT INTO tableA VALUES ('Question B', 2, '2017-06-13', '2017-06-13');
INSERT INTO tableA VALUES ('Question B', 1, '2017-06-13', '2017-06-13');
INSERT INTO tableA VALUES ('Question C', 1, '2017-06-20', '2017-06-20');
INSERT INTO tableA VALUES ('Question C', 1, '2017-06-23', '2017-06-23');
INSERT INTO tableA VALUES ('Question D', 2, '2017-06-01', '2017-06-01');
INSERT INTO tableA VALUES ('Question E', 1, '2017-10-11', '2017-10-11');
INSERT INTO tableA VALUES ('Question E', 1, '2017-10-15', '2017-10-15');
INSERT INTO tableA VALUES ('Question F', 1, '2017-10-20', '2017-10-20');
INSERT INTO tableA VALUES ('Question F', 2, '2017-10-20', '2017-10-20');
INSERT INTO tableA VALUES ('Question F', 2, '2017-10-20', '2017-10-20');
INSERT INTO tableA VALUES ('Question G', 1, '2017-10-26', '2017-10-26');
INSERT INTO tableA VALUES ('Question H', 1, '2017-10-26', '2017-10-26');
INSERT INTO tableA VALUES ('Question H', 2, '2017-10-26', '2017-10-26');
INSERT INTO tableA VALUES ('Question I', 1, '2017-10-26', '2017-10-26');
Here the outcome of your Query:
Question A 2 0 3 66,6667
Question B 2 0 3 66,6667
Question C 2 0 2 100
Question D 0 0 1 0
Question E 2 0 2 100
Question F 1 0 3 33,3333
Question G 1 0 1 100
Question H 1 0 2 50
Question I 1 0 1 100
I could simplify your SQL and have removed some code duplicates, maybe that was your intended question.
DECLARE #StartDate DATE = '2017-06-01';
DECLARE #EndDate DATE = '2017-06-30';
DECLARE #StartDate2 DATE = '2017-10-01';
DECLARE #EndDate2 DATE = '2017-10-30';
WITH
periods AS (
SELECT #StartDate as startdate,
#EndDate as enddate
UNION
SELECT #StartDate2 as startdate,
#EndDate2 as enddate
)
SELECT t.Question, t.Met, t.NA, t.MetNotMet,
CASE WHEN (t.Met) = 0 THEN 0 ELSE ROUND(((CONVERT(FLOAT,(t.Met))/(t.MetNotMet))* 100),4) END as CompRate
FROM (SELECT question,
SUM((CASE WHEN AnswerValue = 1 THEN 1 ELSE 0 END)) Met,
SUM((CASE WHEN AnswerValue = 3 THEN 1 ELSE 0 END)) NA,
SUM((CASE WHEN (ISNULL(AnswerValue,3) <> 3) THEN 1 ELSE 0 END)) MetNotMet
FROM tableA AS a
JOIN ( SELECT p.startdate,
p.enddate,
DATENAME(DAY, p.startdate) + ' ' + DATENAME(MONTH, p.startdate) + ' ' +
DATENAME(YEAR, p.startdate) + ' To ' + DATENAME(DAY, p.enddate) + ' ' +
DATENAME(MONTH, p.enddate) + ' ' + DATENAME(YEAR, p.enddate) AS RepMonthAndYear
FROM periods p ) AS p ON a.startdate >= p.startdate AND a.endate <= p.enddate
GROUP BY a.Question, p.RepMonthAndYear) AS t

SQL Server 2014 Select total for each day

Hello I am working on a dataset for a report in SSRS
and I have a query which gives the total requests in the backlog :
SELECT
COUNT(*) as NB
FROM p_rqt WITH (NOLOCK)
INNER JOIN p_cpy WITH (NOLOCK) ON p_cpy.CpyInCde = p_rqt.OrigCpyInCde
WHERE
CpyTypInCde IN (27, 31)
AND p_rqt.RqtNatInCde IN (74, 75, 76)
AND HeadRqtInCde = 0
AND p_rqt.OrigCpyInCde LIKE CASE WHEN #Client = 0 THEN '%' ELSE #Client END
AND ((RcvDte < DATEADD(day, 1, #DateDeb) AND RqtEndDte IS NULL) OR
(RcvDte < DATEADD(day, 1, #DateDeb) AND RqtEndDte > DATEADD(day, 1, #DateDeb)))
and I want to retrieve the total amount left per day.
I tried lot of things like this :
SELECT CONVERT(date,rcvdte,103), count(*) as nb
FROM p_rqt p WITH (NOLOCK)
INNER JOIN p_cpy WITH (NOLOCK) ON p_cpy.CpyInCde = p.OrigCpyInCde
WHERE
CpyTypInCde IN (27, 31)
AND p.RqtNatInCde IN (74, 75, 76)
AND HeadRqtInCde = 0
AND ((RcvDte < DATEADD(day, 1, '20170901') AND RqtEndDte IS NULL) OR (RcvDte < DATEADD(day, 1, '20170901') AND RqtEndDte > DATEADD(day, 1, '20170901')))
group by CONVERT(date,rcvdte,103)
order by CONVERT(date,rcvdte,103)
I tried inner join subqueries, Sum and other stuff
but all I can manage to do is to have the number of records added per day
and I want something like this :
date: NB:
01/01/2017 1950
02/01/2017 1954 (+4 items)
03/01/2017 1945 (-9 items)
Thank you
Use LAG:
WITH cte AS (
SELECT
CONVERT(date, rcvdte, 103) AS date,
COUNT(*) AS nb
FROM p_rqt p WITH (NOLOCK)
INNER JOIN p_cpy WITH (NOLOCK)
ON p_cpy.CpyInCde = p.OrigCpyInCde
WHERE
CpyTypInCde IN (27, 31) AND
p.RqtNatInCde IN (74, 75, 76) AND
HeadRqtInCde = 0 AND
((RcvDte < DATEADD(day, 1, '20170901') AND RqtEndDte IS NULL) OR (RcvDte < DATEADD(day, 1, '20170901') AND RqtEndDte > DATEADD(day, 1, '20170901')))
GROUP BY CONVERT(date, rcvdte, 103)
ORDER BY CONVERT(date, rcvdte, 103)
)
SELECT
t1.date,
(SELECT SUM(t2.nb) FROM cte t2 WHERE t2.date <= t1.date) AS nb,
CASE WHEN t1.nb - LAG(t1.nb, 1, t1.nb) OVER (ORDER BY t1.date) > 0
THEN '(+' + (t1.nb - LAG(t1.nb, 1, t1.nb) OVER (ORDER BY t1.date)) + ' items)'
ELSE '(' + (t1.nb - LAG(t1.nb, 1, t1.nb) OVER (ORDER BY t1.date)) + ' items)'
END AS difference
FROM cte t1
ORDER BY t1.date;
So i found a solution but it is really slow,
i still post the answer anyway
DECLARE #Tb TABLE ( Colonne1 Datetime, Colonne2 INT )
DECLARE #Debut Datetime = '01/09/2017'
WHILE #Debut < '13/09/2017'
BEGIN
DECLARE #Compteur int = (
SELECT
COUNT(1) NB
FROM p_rqt WITH (NOLOCK)
INNER JOIN p_cpy WITH (NOLOCK) ON p_cpy.CpyInCde = p_rqt.OrigCpyInCde
WHERE
CpyTypInCde IN (27, 31)
AND p_rqt.RqtNatInCde IN (74, 75, 76)
AND HeadRqtInCde = 0
AND p_rqt.OrigCpyInCde LIKE '%'
AND (
(RcvDte < #Debut AND RqtEndDte IS NULL)
OR
(RcvDte < #Debut AND RqtEndDte > #Debut)
)
)
INSERT INTO #Tb (Colonne1, Colonne2) VALUES (#Debut, #Compteur)
SET #Debut = DATEADD(day, 1, #Debut)
IF #Debut > '13/09/2017'
BREAK
ELSE
CONTINUE
END
SELECT * FROM #Tb

joining select statements?

I would like to do a inner join in my query but I don´t know how to summarize my two select statements into one query.
This is the first query:
select
Machine
, EventDefinition
, Duration
, sum(Duration) over (partition by 1) As Total
, Duration/sum(Duration) over (partition by 1)*100 AS Distribution
,case when EventCategory < 0.05 Then 'NOT INCL' ELSE 'OK' END AS Under3Min
from (
Select
SystemName AS Machine
, EventDefinition
, EventDate
, EventStartDateTime
, IsNull(EventEndDateTime, GETDATE()) as EventEndDateTime
, Sum(cast(EventEndDateTime - EventStartDateTime as float))*24 as Duration
,Sum(case when CustomEvent = 'without Stop' then cast(EventEndDateTime - EventStartDateTime as float)*24 else 0 end) as EventCategory
FROM tDataCategory
WHERE EventDate >= #StartDateTime
AND EventDate <= #EndDateTime
AND SystemName = '201'
Group BY SystemName, eventdefinition, eventstartdatetime, eventenddatetime, EventDefinition, EventDate, CustomEvent
) as t
WHERE CustomEvent <> 'without Stop'
OR (CustomEvent = 'without Stop' AND t.EventCategory >=0.05)
group by EventDefinition
, Duration
,Machine
,EventCategory
output:
and my second query:
SELECT DataValue = case when Prod = 0 then 0 else ISNULL(100.0 / Prod * Scrap, 0) end,
Value = GoodUnits/TheoreticalUnits *100,
FROM (
Select intervaldate as DateValue, intervalDateWeek as Datum, tsystem.Name as Name, ProductName as Product, teamname as Team,
SUM(case when IssueName in ('A1', 'A2') then calculationUnitsInitial else 0 end) as Scrap,
Sum(case when IssueName = 'Prod' then calculationUnitsInitial else 0 end) as Prod,
SUM(GoodUnits)
As GoodUnits,
SUM(TheoreticalUnits) As TheoreticalUnits,
from tCount inner join tsystem ON tCount.systemid = tsystem.id
where IntervalDate >= dateadd(wk, datediff(wk, 1, getdate()), 0)
and IntervalDate <= dateadd(wk, datediff(wk, 0, getdate()), 0)
AND ((DATEPART(dw, IntervalDate) + ##DATEFIRST) % 7) NOT IN (0,1)
and tsystem.Name = '201'
group by intervaldate, tsystem.Name, intervaldateweek, ProductName, teamname
) as s
output:
I tried it to add in my query two select statements. But if I do this the output is wrong. I really don´t know how I should join this two queries.
I would like to do then this calculation: Distribution * (1 - Value)
Distribution from the first query and Value from the second query
I assume the first and second result set has to be joined based on A.Machine=B.Name
Try like this,
SELECT A.Distribution * (1 - B.Value)
FROM (
SELECT Machine
,EventDefinition
,Duration
,sum(Duration) OVER (PARTITION BY 1) AS Total
,Duration / sum(Duration) OVER (PARTITION BY 1) * 100 AS Distribution
,CASE
WHEN EventCategory < 0.05
THEN 'NOT INCL'
ELSE 'OK'
END AS Under3Min
FROM (
SELECT SystemName AS Machine
,EventDefinition
,EventDate
,EventStartDateTime
,IsNull(EventEndDateTime, GETDATE()) AS EventEndDateTime
,Sum(cast(EventEndDateTime - EventStartDateTime AS FLOAT)) * 24 AS Duration
,Sum(CASE
WHEN CustomEvent = 'without Stop'
THEN cast(EventEndDateTime - EventStartDateTime AS FLOAT) * 24
ELSE 0
END) AS EventCategory
FROM tDataCategory
WHERE EventDate >= #StartDateTime
AND EventDate <= #EndDateTime
AND SystemName = '201'
GROUP BY SystemName
,eventdefinition
,eventstartdatetime
,eventenddatetime
,EventDefinition
,EventDate
,CustomEvent
) AS t
WHERE CustomEvent <> 'without Stop'
OR (
CustomEvent = 'without Stop'
AND t.EventCategory >= 0.05
)
GROUP BY EventDefinition
,Duration
,Machine
,EventCategory
) A
INNER JOIN (
SELECT DataValue = CASE
WHEN Prod = 0
THEN 0
ELSE ISNULL(100.0 / Prod * Scrap, 0)
END
,Value = GoodUnits / TheoreticalUnits * 100
,NAME
FROM (
SELECT intervaldate AS DateValue
,intervalDateWeek AS Datum
,tsystem.NAME AS NAME
,ProductName AS Product
,teamname AS Team
,SUM(CASE
WHEN IssueName IN (
'A1'
,'A2'
)
THEN calculationUnitsInitial
ELSE 0
END) AS Scrap
,Sum(CASE
WHEN IssueName = 'Prod'
THEN calculationUnitsInitial
ELSE 0
END) AS Prod
,SUM(GoodUnits) AS GoodUnits
,SUM(TheoreticalUnits) AS TheoreticalUnits
,
FROM tCount
INNER JOIN tsystem ON tCount.systemid = tsystem.id
WHERE IntervalDate >= dateadd(wk, datediff(wk, 1, getdate()), 0)
AND IntervalDate <= dateadd(wk, datediff(wk, 0, getdate()), 0)
AND ((DATEPART(dw, IntervalDate) + ##DATEFIRST) % 7) NOT IN (
0
,1
)
AND tsystem.NAME = '201'
GROUP BY intervaldate
,tsystem.NAME
,intervaldateweek
,ProductName
,teamname
) AS s
) B ON A.Machine = B.NAME

Joining two queries into one

I have two working queries. Query 1 performs a filter on a large table and returns exactly the data that I need, it looks like this:
/****** QUERY #1 - This query will filter the data ******/
SELECT [WacnId],
[StartDT]
,[EndDT]
,[Group]
,[ID_Agency]
,[TargetUnit_Agency],
case [Group]
when 1 then 'in'
when 0 then 'out'
end as traffic
FROM [GW_20140315].[dbo].[ARC_Calls_ReportView]
WHERE [GroupDisplayID] = 'T802149' OR [ID_Agency] = 'Dispatch' or [TargetUnit_Agency] = 'Dispatch'
order by StartDT
Query #2 acts on the filtered data from Query 1 and produces a 1/2 hourly report. Query 2 looks like this:
/******Query #2- This query will take the filtered data and process it as needed ******/
SELECT dateadd(mi, (datediff(mi, 0, StartDT) / 30) * 30, 0) as HalfHour
, sum(DATEDIFF ( s , [StartDT] , [EndDT] )) as [Total Time (Seconds)],
SUM(CASE WHEN [TargetUnit_Agency] = 'Dispatch' then 1 ELSE 0 END ) AS InCount,
SUM(CASE WHEN [ID_Agency] = 'Dispatch' then 1 ELSE 0 END ) AS OutCount
FROM [Radio].[dbo].[Filter_Data]--This is how I did it before, but now I want to combine the two queries
GROUP BY dateadd(mi, (datediff(mi, 0, StartDT) / 30) * 30, 0)
ORDER BY 1
How may I combine these two queries into one?
You may use a CTE to describe your filtered data (first query) and then query using the CTE as your main table (second query):
;WITH FilteredCTE AS
(
SELECT [WacnId],
[StartDT]
,[EndDT]
,[Group]
,[ID_Agency]
,[TargetUnit_Agency],
case [Group]
when 1 then 'in'
when 0 then 'out'
end as traffic
FROM [GW_20140315].[dbo].[ARC_Calls_ReportView]
WHERE [GroupDisplayID] = 'T802149'
OR [ID_Agency] = 'Dispatch'
or [TargetUnit_Agency] = 'Dispatch'
)
SELECT dateadd(mi, (datediff(mi, 0, StartDT) / 30) * 30, 0) as HalfHour,
sum(DATEDIFF ( s , [StartDT] , [EndDT] )) as [Total Time (Seconds)],
SUM(CASE WHEN [TargetUnit_Agency] = 'Dispatch' then 1 ELSE 0 END ) AS InCount,
SUM(CASE WHEN [ID_Agency] = 'Dispatch' then 1 ELSE 0 END ) AS OutCount
FROM FilteredCTE
GROUP BY dateadd(mi, (datediff(mi, 0, StartDT) / 30) * 30, 0)
ORDER BY StartDT
Just select Query1 FROM Query2:
SELECT Dateadd(mi, ( Datediff(mi, 0, startdt) / 30 ) * 30, 0) AS HalfHour,
Sum(Datediff (s, [startdt], [enddt])) AS
[Total Time (Seconds)],
Sum(CASE
WHEN [targetunit_agency] = 'Dispatch' THEN 1
ELSE 0
end) AS InCount,
Sum(CASE
WHEN [id_agency] = 'Dispatch' THEN 1
ELSE 0
end) AS OutCount
FROM (SELECT [wacnid],
[startdt],
[enddt],
[group],
[id_agency],
[targetunit_agency],
CASE [group]
WHEN 1 THEN 'in'
WHEN 0 THEN 'out'
end AS traffic
FROM [GW_20140315].[dbo].[arc_calls_reportview]
WHERE [groupdisplayid] = 'T802149'
OR [id_agency] = 'Dispatch'
OR [targetunit_agency] = 'Dispatch'
ORDER BY startdt)
GROUP BY Dateadd(mi, ( Datediff(mi, 0, startdt) / 30 ) * 30, 0)
ORDER BY 1