Get DATE when Price Changed - sql

Im trying to perform some DATEDIFF calculations but i simply lack the knowledge to complete the task.
I got a table that keeps record of the articles sold with date when the operation took place and historic prices of the article. Since i live in a country with 30% of anual inflation. I must consider that factor to calculate the earning by every article sold.
It all works fine while i have the buying price saved and the date when a product price change took place. But, when that data was not saved as an approximation i would like to use the date when the operation with a different price took place.
As result of the following select operations:
USE Rusich
DECLARE
#IDNegocio AS INT,
#UsarIDProducto AS BIT,
#IDProducto AS VARCHAR(50),
#FechaInicio AS DATE,
#FechaFinal AS DATE,
#TamaƱoMinimoDeMuestra AS INT,
#SeVendeMinimoCadaXDias AS INT,
#Inflacion AS DECIMAL(18,3),
#AuxMargen AS DECIMAL(18,2),
#AuxDifDias AS INT;
SET #FechaInicio = '01/02/10';
SET #FechaFinal = '28/02/18';
SET #IDNegocio = 1;
SET #IDProducto = '6910101404918'; /*<<<< Cambiar a NULL segun necesidad*/
SET #TamaƱoMinimoDeMuestra = 1;
SET #SeVendeMinimoCadaXDias = 90;
SET #Inflacion = 0.083;
SELECT
AUXFechas.IDProducto,
AUXFechas.[$ Precio de Venta Historico],
AUXFechas.[Fecha Precio],
AUXFechas.[Fecha Venta],
AUXFechas.FechaAnterior,
AUXFechas.DiasDiferencia,
CAST(
CASE WHEN
AUXFechas.IDProducto NOT IN ('112', '113' , '114')
AND AUXFechas.[Fecha Precio] <= AUXFechas.[Fecha Venta]
AND StockDetalles.[Precio de Compra] <> 0
AND StockDetalles.[Precio de Compra] IS NOT NULL THEN
(1 - StockDetalles.[Precio de Compra] / AUXFechas.[$ Precio de Venta Historico]) * 100 - (AUXFechas.[$ Descuento]/100) - DATEDIFF(DAY, AUXFechas.[Fecha Precio], AUXFechas.[Fecha Venta]) * #Inflacion
ELSE
NULL
END
AS DECIMAL(18,2)) AS [% Margen Ganancia Real]
FROM
StockDetalles JOIN (
SELECT
Stock.ID AS IDProducto,
Stock.Cantidad AS #Disponible,
Recibos.Cantidad as [#Vendida],
Recibos.Precio AS [$ Precio de Venta Historico],
Recibos.Descuento AS [$ Descuento],
Stock.[Precio de Venta] AS [$ Precio],
Stock.[Fecha Actualizacion de Precio] AS [Fecha Precio],
CAST(RecibosRegistros.Fecha AS DATE) AS [Fecha Venta],
ISNULL(LAG(CAST(RecibosRegistros.Fecha AS DATE), 1) OVER (PARTITION BY Recibos.IDProducto ORDER BY RecibosRegistros.Fecha), Stock.[Fecha Actualizacion de Precio]) AS FechaAnterior,
/*Considera el caso cuando no existe un registro anterior y usa la fecha de actualizacion de precio si es posible*/
CASE WHEN (LAG(CAST(RecibosRegistros.Fecha AS DATE), 1) OVER (PARTITION BY Recibos.IDProducto ORDER BY RecibosRegistros.Fecha) IS NULL) AND CAST(RecibosRegistros.Fecha AS DATE) > Stock.[Fecha Actualizacion de Precio] THEN
(DATEDIFF(DAY, CAST(RecibosRegistros.Fecha AS DATE),
/*PARTITION BY PARTICIONA POR COLUMNA*/
ISNULL(LAG(CAST(RecibosRegistros.Fecha AS DATE), 1) OVER (PARTITION BY Recibos.IDProducto ORDER BY RecibosRegistros.Fecha), [Fecha Actualizacion de Precio])) / Recibos.Cantidad) * -1
ELSE
(DATEDIFF(DAY, CAST(RecibosRegistros.Fecha AS DATE),
/*PARTITION BY PARTICIONA POR COLUMNA*/
LAG(CAST(RecibosRegistros.Fecha AS DATE), 1) OVER (PARTITION BY Recibos.IDProducto ORDER BY RecibosRegistros.Fecha)) / Recibos.Cantidad) * -1
END AS DiasDiferencia
FROM
RecibosRegistros
JOIN Recibos ON RecibosRegistros.IDRecibo = Recibos.IDRecibo
JOIN Stock ON Recibos.IDProducto = Stock.ID
WHERE
RecibosRegistros.NegocioID = #IDNegocio
AND Stock.IDNegocio = #IDNegocio
AND Stock.ID != '111'
AND Stock.ID != '112'
AND Stock.ID != '113'
AND Stock.ID != '114'
AND Stock.ID = COALESCE(#IDProducto,Stock.ID)) AS AUXFechas ON StockDetalles.ID = AUXFechas.IDProducto
JOIN Categorias ON StockDetalles.CategoriaID = Categorias.ID
Im obtaining this result:
IDProducto $ Precio de Venta Historico Fecha Precio Fecha Venta FechaAnterior DiasDiferencia % Margen Ganancia Real
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
6910101404918 15,00 2012-10-18 2012-07-23 2012-10-18 NULL NULL
6910101404918 15,00 2012-10-18 2012-09-01 2012-07-23 40 NULL
6910101404918 21,00 2012-10-18 2013-07-01 2012-09-01 303 NULL
6910101404918 21,00 2012-10-18 2013-09-02 2013-07-01 63 NULL
6910101404918 21,00 2012-10-18 2013-09-24 2013-09-02 22 NULL
0200002003867 28,00 2014-03-05 2014-07-08 2014-03-05 125 NULL
0200002003867 28,00 2014-03-05 2014-07-08 2014-07-08 0 NULL
0200002003867 28,00 2014-03-05 2014-10-23 2014-07-08 107 NULL
0200002003867 28,00 2014-03-05 2015-01-21 2014-10-23 90 NULL
0200002003867 28,00 2014-03-05 2015-04-06 2015-01-21 75 NULL
What i need to do is get a column with date (Fecha Precio) where [$ Precio de Venta Historico] changed.
Output should be:
IDProducto $ Precio de Venta Historico Fecha Precio Fecha Venta FechaAnterior DiasDiferencia % Margen Ganancia Real Fecha Cambio
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
6910101404918 15,00 2012-10-18 2012-07-23 2012-10-18 NULL NULL NULL
6910101404918 15,00 2012-10-18 2012-09-01 2012-07-23 40 NULL 2012-10-18
6910101404918 21,00 2012-10-18 2013-07-01 2012-09-01 303 NULL NULL
6910101404918 21,00 2012-10-18 2013-09-02 2013-07-01 63 NULL 2012-09-01
6910101404918 21,00 2012-10-18 2013-09-24 2013-09-02 22 NULL 2012-09-01
0200002003867 28,00 2014-03-05 2014-07-08 2014-03-05 125 NULL NULL
0200002003867 28,00 2014-03-05 2014-07-08 2014-07-08 0 NULL 2014-07-08
0200002003867 28,00 2014-03-05 2014-10-23 2014-07-08 107 NULL 2014-07-08
0200002003867 28,00 2014-03-05 2015-01-21 2014-10-23 90 NULL 2014-07-08
0200002003867 28,00 2014-03-05 2015-04-06 2015-01-21 75 NULL 2014-07-08
My guess is that the solution must be related with LAG/LEAD and PartitionBY IDProducto but i dont know how to do it. Please Help

Added this code to try to get some result and i almost got it but not quite yet:
LAG(AUXFechas.[Fecha Venta], 1, NULL) OVER (PARTITION BY IDProducto, AUXFechas.[$ Precio de Venta Historico] ORDER BY AUXFechas.[Fecha Venta])
GOT:
6910101404918 Bandeja Plastica Borde Dorado Oval 23 Bazar 0 1 15,00 21,00 2012-10-18 2012-07-23 2012-10-18 NULL NULL NULL
6910101404918 Bandeja Plastica Borde Dorado Oval 23 Bazar 0 1 15,00 21,00 2012-10-18 2012-09-01 2012-07-23 40 NULL 2012-07-23
6910101404918 Bandeja Plastica Borde Dorado Oval 23 Bazar 0 1 21,00 21,00 2012-10-18 2013-07-01 2012-09-01 303 NULL NULL
6910101404918 Bandeja Plastica Borde Dorado Oval 23 Bazar 0 1 21,00 21,00 2012-10-18 2013-09-02 2013-07-01 63 NULL 2013-07-01
6910101404918 Bandeja Plastica Borde Dorado Oval 23 Bazar 0 1 21,00 21,00 2012-10-18 2013-09-24 2013-09-02 22 NULL 2013-09-02
That last date (2013-09-02) Should be the same as previous (2013-07-01)
Tryed with another product and got:
0200002003867 Bandeja Acero Oval 21cm Bazar 0 1 28,00 28,00 2014-03-05 2014-07-08 2014-03-05 125 NULL NULL
0200002003867 Bandeja Acero Oval 21cm Bazar 0 1 28,00 28,00 2014-03-05 2014-07-08 2014-07-08 0 NULL 2014-07-08
0200002003867 Bandeja Acero Oval 21cm Bazar 0 1 28,00 28,00 2014-03-05 2014-10-23 2014-07-08 107 NULL 2014-07-08
0200002003867 Bandeja Acero Oval 21cm Bazar 0 1 28,00 28,00 2014-03-05 2015-01-21 2014-10-23 90 NULL 2014-10-23
0200002003867 Bandeja Acero Oval 21cm Bazar 0 1 28,00 28,00 2014-03-05 2015-04-06 2015-01-21 75 NULL 2015-01-21
Only the first cell after NULL in the right column is OK but the rest sould be the same

Finally got what i wanted by using the FIRST_VALUE function:
FIRST_VALUE(AUXFechas.[Fecha Venta]) OVER (PARTITION BY AUXFechas.IDProducto, AUXFechas. [$ Precio de Venta Historico] ORDER BY AUXFechas.[Fecha Venta])
AND GOT THIS!:
IDProducto Fecha Precio Fecha Venta FechaAnterior DiasDiferencia (Sin nombre de columna)
7790002000483 2014-08-28 2012-04-14 2014-08-28 NULL 2012-04-14
7790002000483 2014-08-28 2012-05-03 2012-04-14 19 2012-04-14
7790002000483 2014-08-28 2012-05-03 2012-05-03 0 2012-04-14
7790002000483 2014-08-28 2012-06-02 2012-05-03 30 2012-04-14
7790002000483 2014-08-28 2012-06-02 2012-06-02 0 2012-04-14
7790002000483 2014-08-28 2012-06-02 2012-06-02 0 2012-04-14
7790002000483 2014-08-28 2012-06-18 2012-06-02 16 2012-04-14
7790002000483 2014-08-28 2012-07-05 2012-06-18 17 2012-04-14
7790002000483 2014-08-28 2012-07-14 2012-07-05 4 2012-04-14
7790002000483 2014-08-28 2012-07-20 2012-07-14 6 2012-04-14
7790002000483 2014-08-28 2012-07-23 2012-07-20 3 2012-04-14
7790002000483 2014-08-28 2012-07-23 2012-07-23 0 2012-04-14
7790002000483 2014-08-28 2013-01-30 2012-07-23 191 2013-01-30
7790002000483 2014-08-28 2013-07-20 2013-01-30 171 2013-01-30
7790002000483 2014-08-28 2013-10-16 2013-07-20 88 2013-01-30
7790002000483 2014-08-28 2015-07-14 2013-10-16 636 2015-07-14

Related

How to count the number of campaigns per day based on the start and end dates of the campaigns in SQL

I need to count the number of campaigns per day based on the start and end dates of the campaigns
Input Table:
Campaign name
Start date
End date
Campaign A
2022-07-10
2022-09-25
Campaign B
2022-08-06
2022-10-07
Campaign C
2022-07-30
2022-09-10
Campaign D
2022-08-26
2022-10-24
Campaign E
2022-07-17
2022-09-29
Campaign F
2022-08-24
2022-09-12
Campaign G
2022-08-11
2022-10-24
Campaign H
2022-08-26
2022-11-22
Campaign I
2022-08-29
2022-09-25
Campaign J
2022-08-21
2022-11-15
Campaign K
2022-07-20
2022-09-18
Campaign L
2022-07-31
2022-11-20
Campaign M
2022-08-17
2022-10-10
Campaign N
2022-07-27
2022-09-07
Campaign O
2022-07-29
2022-09-26
Campaign P
2022-07-06
2022-09-15
Campaign Q
2022-07-16
2022-09-22
Out needed (result):
Date
Count unique campaigns
2022-07-02
17
2022-07-03
47
2022-07-04
5
2022-07-05
5
2022-07-06
25
2022-07-07
27
2022-07-08
17
2022-07-09
58
2022-07-10
23
2022-07-11
53
2022-07-12
18
2022-07-13
29
2022-07-14
52
2022-07-15
7
2022-07-16
17
2022-07-17
37
2022-07-18
33
How do I need to write the SQL command to get the above result? thanks all
In the following solutions we leverage string_split with combination with replicate to generate new records.
select dt as date
,count(*) as Count_unique_campaigns
from
(
select *
,dateadd(day, row_number() over(partition by Campaign_name order by (select null))-1, Start_date) as dt
from (
select *
from t
outer apply string_split(replicate(',',datediff(day, Start_date, End_date)),',')
) t
) t
group by dt
order by dt
date
Count_unique_campaigns
2022-07-06
1
2022-07-07
1
2022-07-08
1
2022-07-09
1
2022-07-10
2
2022-07-11
2
2022-07-12
2
2022-07-13
2
2022-07-14
2
2022-07-15
2
2022-07-16
3
2022-07-17
4
2022-07-18
4
2022-07-19
4
2022-07-20
5
2022-07-21
5
2022-07-22
5
2022-07-23
5
2022-07-24
5
2022-07-25
5
2022-07-26
5
2022-07-27
6
2022-07-28
6
2022-07-29
7
2022-07-30
8
2022-07-31
9
2022-08-01
9
2022-08-02
9
2022-08-03
9
2022-08-04
9
2022-08-05
9
2022-08-06
10
2022-08-07
10
2022-08-08
10
2022-08-09
10
2022-08-10
10
2022-08-11
11
2022-08-12
11
2022-08-13
11
2022-08-14
11
2022-08-15
11
2022-08-16
11
2022-08-17
12
2022-08-18
12
2022-08-19
12
2022-08-20
12
2022-08-21
13
2022-08-22
13
2022-08-23
13
2022-08-24
14
2022-08-25
14
2022-08-26
16
2022-08-27
16
2022-08-28
16
2022-08-29
17
2022-08-30
17
2022-08-31
17
2022-09-01
17
2022-09-02
17
2022-09-03
17
2022-09-04
17
2022-09-05
17
2022-09-06
17
2022-09-07
17
2022-09-08
16
2022-09-09
16
2022-09-10
16
2022-09-11
15
2022-09-12
15
2022-09-13
14
2022-09-14
14
2022-09-15
14
2022-09-16
13
2022-09-17
13
2022-09-18
13
2022-09-19
12
2022-09-20
12
2022-09-21
12
2022-09-22
12
2022-09-23
11
2022-09-24
11
2022-09-25
11
2022-09-26
9
2022-09-27
8
2022-09-28
8
2022-09-29
8
2022-09-30
7
2022-10-01
7
2022-10-02
7
2022-10-03
7
2022-10-04
7
2022-10-05
7
2022-10-06
7
2022-10-07
7
2022-10-08
6
2022-10-09
6
2022-10-10
6
2022-10-11
5
2022-10-12
5
2022-10-13
5
2022-10-14
5
2022-10-15
5
2022-10-16
5
2022-10-17
5
2022-10-18
5
2022-10-19
5
2022-10-20
5
2022-10-21
5
2022-10-22
5
2022-10-23
5
2022-10-24
5
2022-10-25
3
2022-10-26
3
2022-10-27
3
2022-10-28
3
2022-10-29
3
2022-10-30
3
2022-10-31
3
2022-11-01
3
2022-11-02
3
2022-11-03
3
2022-11-04
3
2022-11-05
3
2022-11-06
3
2022-11-07
3
2022-11-08
3
2022-11-09
3
2022-11-10
3
2022-11-11
3
2022-11-12
3
2022-11-13
3
2022-11-14
3
2022-11-15
3
2022-11-16
2
2022-11-17
2
2022-11-18
2
2022-11-19
2
2022-11-20
2
2022-11-21
1
2022-11-22
1
For SQL in Azure and SQL Server 2022 we have a cleaner solution based on [ordinal][4].
"The enable_ordinal argument and ordinal output column are currently
supported in Azure SQL Database, Azure SQL Managed Instance, and Azure
Synapse Analytics (serverless SQL pool only). Beginning with SQL
Server 2022 (16.x) Preview, the argument and output column are
available in SQL Server."
select dt as date
,count(*) as Count_unique_campaigns
from
(
select *
,dateadd(day, ordinal-1, Start_date) as dt
from (
select *
from t
outer apply string_split(replicate(',',datediff(day, Start_date, End_date)),',', 1)
) t
) t
group by dt
order by dt
Fiddle
Your sample data doesn't seem to match your desired results, but I think what you're after is this:
DECLARE #Start date, #End date;
-- first, find the earliest and last date:
SELECT #Start = MIN([Start date]), #End = MAX([End date])
FROM dbo.Campaigns;
-- now use a recursive CTE to build a date range,
-- and count the number of campaigns that have a row
-- where the campaign was active on that date:
WITH d(d) AS
(
SELECT #Start
UNION ALL
SELECT DATEADD(DAY, 1, d) FROM d WHERE d < #End
)
SELECT
[Date] = d,
[Count unique campaigns] = COUNT(*)
FROM d
INNER JOIN dbo.Campaigns AS c
ON d.d >= c.[Start date] AND d.d <= c.[End date]
GROUP BY d.d OPTION (MAXRECURSION 32767);
Working example in this fiddle.

Following Start and End Date Columns

I have start and end date columns, and there are some where the start date equals the end date of the previous row without a gap. I'm trying to get it so that it would basically go from the Start Date row who's End Date is null and kinda "zig-zag" up going until the Start Date does not match the End Date.
I've tried CTEs, and ROW_NUMBER() OVER().
START_DTE END_DTE
2018-01-17 2018-01-19
2018-01-26 2018-02-22
2018-02-22 2018-08-24
2018-08-24 2018-09-24
2018-09-24 NULL
Expected:
START_DTE END_DTE
2018-01-26 2018-09-24
EDIT
Using a proposed solution with an added CTE to ensure dates don't have times with them.
WITH
CTE_TABLE_NAME AS
(
SELECT
ID_NUM,
CONVERT(DATE,START_DTE) START_DTE,
CONVERT(DATE,END_DTE) END_DTE
FROM
TABLE_NAME
WHERE ID_NUM = 123
)
select min(start_dte) as start_dte, max(end_dte) as end_dte, grp
from (select t.*,
sum(case when prev_end_dte = end_dte then 0 else 1 end) over (order by start_dte) as grp
from (select t.*,
lag(end_dte) over (order by start_dte) as prev_end_dte
from CTE_TABLE_NAME t
) t
) t
group by grp;
The following query provides these results:
start_dte end_dte grp
2014-08-24 2014-12-19 1
2014-08-31 2014-09-02 2
2014-09-02 2014-09-18 3
2014-09-18 2014-11-03 4
2014-11-18 2014-12-09 5
2014-12-09 2015-01-16 6
2015-01-30 2015-02-02 7
2015-02-02 2015-05-15 8
2015-05-15 2015-07-08 9
2015-07-08 2015-07-09 10
2015-07-09 2015-08-25 11
2015-08-31 2015-09-01 12
2015-10-06 2015-10-29 13
2015-11-10 2015-12-11 14
2015-12-11 2015-12-15 15
2015-12-15 2016-01-20 16
2016-01-29 2016-02-01 17
2016-02-01 2016-03-03 18
2016-03-30 2016-08-29 19
2016-08-30 2016-12-06 20
2017-01-27 2017-02-20 21
2017-02-20 2017-08-15 22
2017-08-15 2017-08-29 23
2017-08-29 2018-01-17 24
2018-01-17 2018-01-19 25
2018-01-26 2018-02-22 26
2018-02-22 2018-08-24 27
2018-08-24 2018-09-24 28
2018-09-24 NULL 29
I tried using having count (*) > 1 as suggested, but it provided no results
Expected example
START_DTE END_DTE
2017-01-27 2018-01-17
2018-01-26 2018-09-24
You can identify where groups of connected rows start by looking for where adjacent rows are not connected. A cumulative sum of these starts then gives you the groups.
select min(start_dte) as start_dte, max(end_dte) as end_dte
from (select t.*,
sum(case when prev_end_dte = start_dte then 0 else 1 end) over (order by start_dte) as grp
from (select t.*,
lag(end_dte) over (order by start_dte) as prev_end_dte
from t
) t
) t
group by grp;
If you want only multiply connected rows (as implied by your question), then add having count(*) > 1 to the outer query.
Here is a db<>fiddle.

Case when Statement Not Working with my data

While Working case statement i got stuck
For Eg i have below scenario
Amt StartDate EndDate Port Trade
10.00 9/21/2018 9/21/2020 NULL NULL
54,523.00 11/14/2018 11/15/2018 NULL NULL
756.00 11/14/2018 11/15/2018 NULL NULL
456.00 11/14/2018 11/15/2018 NULL NULL
86.00 11/14/2018 11/15/2018 NULL NULL
86.00 11/14/2018 11/15/2018 NULL NULL
453.00 11/14/2018 11/15/2018 NULL NULL
786.00 11/14/2018 11/15/2018 NULL NULL
86.00 11/14/2018 11/15/2018 NULL NULL
568.00 11/14/2018 11/15/2018 NULL NULL
12,358.00 11/14/2018 11/15/2018 NULL NULL
45,388.00 11/5/2018 12/5/2018 NULL NULL
75,368.00 8/9/2018 12/20/2018 call collateral
783,678.00 7/13/2018 1/14/2019 NULL NULL
1)what i am looking for is when startdate and enddate difference = 1
or Port like '%call%' and Trade='collateral' then amt
2) when startdate and enddate difference > 7
and Port not like '%call%' and Trade <> 'collateral' then amt
My First Condition Works
select CASE WHEN DATEDIFF(DAY,CAST(Startdate AS DATE),CAST(Enddate AS DATE))=1
OR (Port like 'Call' and [Trade]='collateral')
THEN amt ELSE 0 END AS money1
from tablename
But Second Condition not Working
select CASE WHEN (DATEDIFF(DAY,CAST(Startdate AS DATE),CAST(Enddate AS DATE))> 7 AND
DATEDIFF(DAY,CAST(Startdate AS DATE),CAST(Enddate AS DATE)) <= 9999)
and [Trade] <> 'collateral' and Portfolio not like '%Call%'
THEN amt ELSE 0 END AS money2 from tablename
excepted o/p
Amt StartDate EndDate money1 money2
10.00 9/21/2018 9/21/2020 10.00
54,523.00 11/14/2018 11/15/2018 54,523.00
756.00 11/14/2018 11/15/2018 756.00
456.00 11/14/2018 11/15/2018 456.00
86.00 11/14/2018 11/15/2018 86.00
86.00 11/14/2018 11/15/2018 86.00
453.00 11/14/2018 11/15/2018 453.00
786.00 11/14/2018 11/15/2018 786.00
86.00 11/14/2018 11/15/2018 86.00
568.00 11/14/2018 11/15/2018 568.00
12,358.00 11/14/2018 11/15/2018 12,358.00
45,388.00 11/5/2018 12/5/2018 45,388.00
75,368.00 8/9/2018 12/20/2018 75,368.00
783,678.00 7/13/2018 1/14/2019 783,678.00
Need Help i am using Sql server 2012.
Check whether PortFolio and Trade are NULL.
So:
SELECT CASE WHEN DATEDIFF(DAY,CAST(Startdate AS DATE),CAST(Enddate AS DATE))> 7 AND
DATEDIFF(DAY,CAST(Startdate AS DATE),CAST(Enddate AS DATE)) <= 9999 AND
([Trade] IS NULL OR [Trade] <> 'collateral') AND
(Portfolio IS NULL OR Portfolio NOT LIKE '%call%')
THEN amt ELSE 0 END AS money2
FROM tablename;
Your like operator should be '%Call%'
select CASE WHEN (DATEDIFF(DAY,CAST(Startdate AS DATE),CAST(Enddate AS DATE))> 7 AND
DATEDIFF(DAY,CAST(Startdate AS DATE),CAST(Enddate AS DATE)) <= 9999)
and [Trade] <> 'collateral' and Portfolio not like '%Call%'
THEN amt ELSE 0 END AS money2 from tablename

How to get time between calls in SQL?

I need to get the average time between phone calls per agent at one of our call centers. These are the queries I have thus far:
--This query gets all the agentIDs and their callstarts and callends, and as far as I know, attaches an incrementing row-number to them.
drop table #thuranin
SELECT AgentID, CallStart, CallEnd, row_number() over (order by (select NULL)) AS rowInt
INTO #thuranin
FROM Main.CallRecord
WHERE DialerPoolManagementID is null and incomingcall = 0
ORDER BY AgentID
--This query attempts to get the time between each call
drop table #ploto
SELECT nin.AgentID, (CAST(ISNULL(th.CallStart, 0) - nin.CallEnd AS float)) AS AverageTimeBetween
INTO #ploto
FROM #thuranin nin
LEFT JOIN #thuranin AS th ON th.rowInt = (SELECT MIN(rowInt) FROM #thuranin WHERE rowInt > #thuranin.rowInt AND AgentID=th.AgentID)
--This query should average the times by agent
SELECT agentID, AVG(ABS(AverageTimeBetween)) as avGTimebwn
FROM #ploto
WHERE ABS(AverageTimeBetween) > 20000
GROUP BY AgentID
However, this fails (hence why I'm here). It returns values in the -40000's, and I'm not entirely sure why. I need to get the average amount of time between a call end and a call start per agent.
I know that calls at the end of the day to start of the next day could be inflating that number, but I'm unsure of how to deal with that either.
Here's a sample hundred rows from the #thuranin temporary table, if it helps:
AgentID CallStart CallEnd rowInt
NULL 2013-05-29 13:48:39.000 2013-05-29 13:57:20.000 139541
191 2013-05-29 13:50:16.000 2013-05-29 13:50:43.000 139581
NULL 2013-05-29 13:52:04.000 2013-05-29 13:52:46.000 139621
115 2013-05-29 13:53:20.000 2013-05-29 13:53:21.000 139661
190 2013-05-29 13:56:27.000 2013-05-29 13:57:59.000 139701
NULL 2013-05-29 13:58:46.000 2013-05-29 13:59:44.000 139741
171 2013-05-03 18:37:07.000 2013-05-03 18:37:14.000 139781
NULL 2013-05-03 18:39:49.000 2013-05-03 18:41:52.000 139821
107 2013-05-03 18:42:32.000 2013-05-03 18:42:38.000 139861
184 2013-05-03 18:45:38.000 2013-05-03 18:46:08.000 139901
NULL 2013-05-03 18:47:07.000 2013-05-03 18:47:57.000 139941
31 2013-06-14 15:22:02.000 2013-06-14 15:22:44.000 139981
31 2013-06-14 15:24:47.000 2013-06-14 15:25:16.000 140021
31 2013-06-14 15:29:10.000 2013-06-14 15:29:11.000 140061
31 2013-06-14 15:33:57.000 2013-06-14 15:34:06.000 140101
31 2013-06-14 15:41:32.000 2013-06-14 15:42:18.000 140141
172 2013-04-24 21:48:47.000 2013-04-24 21:51:45.000 140181
169 2013-04-24 21:50:42.000 2013-04-24 21:50:53.000 140221
65 2013-04-24 21:52:47.000 2013-04-24 21:52:54.000 140261
169 2013-04-24 21:57:49.000 2013-04-24 21:57:57.000 140301
NULL 2013-04-24 22:04:59.000 2013-04-24 22:06:11.000 140341
31 2013-06-20 14:37:45.000 2013-06-20 14:38:29.000 140381
31 2013-06-20 14:40:27.000 2013-06-20 14:41:09.000 140421
31 2013-06-20 14:44:05.000 2013-06-20 14:44:39.000 140461
31 2013-06-20 14:50:53.000 2013-06-20 14:51:17.000 140501
31 2013-06-20 14:58:52.000 2013-06-20 14:59:24.000 140541
31 2013-07-10 19:54:21.000 2013-07-10 19:54:31.000 140581
31 2013-07-10 20:01:24.000 2013-07-10 20:01:51.000 140621
31 2013-07-10 20:06:23.000 2013-07-10 20:07:14.000 140661
31 2013-07-10 20:09:46.000 2013-07-10 20:09:56.000 140701
31 2013-07-10 20:12:10.000 2013-07-10 20:12:49.000 140741
31 2013-07-10 20:14:45.000 2013-07-10 20:14:59.000 140781
175 2013-07-01 22:35:54.000 2013-07-01 22:36:14.000 140821
191 2013-07-01 22:42:29.000 2013-07-01 22:43:43.000 140861
175 2013-07-01 22:49:42.000 2013-07-01 22:49:57.000 140901
107 2013-07-01 22:59:39.000 2013-07-01 23:00:48.000 140941
191 2013-07-01 23:09:52.000 2013-07-01 23:10:52.000 140981
NULL 2013-04-02 15:47:14.000 2013-04-02 15:48:06.000 141021
NULL 2013-04-02 15:48:48.000 2013-04-02 15:49:07.000 141061
NULL 2013-04-02 15:50:03.000 2013-04-02 15:50:53.000 141101
196 2013-04-02 15:52:05.000 2013-04-02 15:52:52.000 141141
NULL 2013-04-02 15:53:03.000 2013-04-02 15:53:06.000 141181
NULL 2013-05-08 16:17:54.000 2013-05-08 16:18:10.000 141221
140 2013-05-08 16:19:53.000 2013-05-08 16:20:05.000 141261
188 2013-05-08 16:21:34.000 2013-05-08 16:38:04.000 141301
NULL 2013-05-08 16:23:22.000 2013-05-08 16:25:02.000 141341
NULL 2013-05-08 16:25:16.000 2013-05-08 16:27:02.000 141381
31 2013-07-01 23:13:21.000 2013-07-01 23:14:24.000 141421
31 2013-07-01 23:24:23.000 2013-07-01 23:25:23.000 141461
31 2013-07-01 23:40:14.000 2013-07-01 23:40:50.000 141501
31 2013-07-01 23:44:35.000 2013-07-01 23:45:18.000 141541
31 2013-07-01 23:51:58.000 2013-07-01 23:54:33.000 141581
31 2013-07-02 13:03:17.000 2013-07-02 13:04:21.000 141621
158 2013-07-02 13:10:14.000 2013-07-02 13:11:09.000 141661
189 2013-07-02 13:13:48.000 2013-07-02 13:13:55.000 141701
202 2013-07-02 13:16:42.000 2013-07-02 13:16:42.000 141741
107 2013-07-02 13:19:31.000 2013-07-02 13:19:48.000 141781
31 2013-07-02 13:22:31.000 2013-07-02 13:24:44.000 141821
NULL 2013-03-21 18:59:22.000 2013-03-21 19:00:20.000 141861
NULL 2013-03-21 19:01:20.000 2013-03-21 19:01:30.000 141901
112 2013-03-21 19:03:29.000 2013-03-21 19:04:02.000 141941
159 2013-03-21 19:05:27.000 2013-03-21 19:06:31.000 141981
169 2013-03-21 19:07:25.000 2013-03-21 19:08:32.000 142021
NULL 2013-03-15 14:03:40.000 2013-03-15 14:04:14.000 142061
NULL 2013-03-15 14:04:41.000 2013-03-15 14:05:01.000 142101
NULL 2013-03-15 14:06:08.000 2013-03-15 14:07:10.000 142141
NULL 2013-03-15 14:07:47.000 2013-03-15 14:08:48.000 142181
65 2013-03-15 14:09:02.000 2013-03-15 14:09:17.000 142221
183 2013-05-21 17:25:14.000 2013-05-21 17:26:29.000 142261
NULL 2013-05-21 17:27:59.000 2013-05-21 17:28:35.000 142301
NULL 2013-05-21 17:31:42.000 2013-05-21 17:32:47.000 142341
166 2013-05-21 17:35:05.000 2013-05-21 17:36:01.000 142381
182 2013-05-21 17:37:38.000 2013-05-21 17:37:48.000 142421
166 2013-05-21 17:39:46.000 2013-05-21 17:40:21.000 142461
166 2013-04-24 22:13:50.000 2013-04-24 22:14:46.000 142501
65 2013-04-24 22:22:18.000 2013-04-24 22:22:21.000 142541
182 2013-04-24 22:25:54.000 2013-04-24 22:26:01.000 142581
116 2013-04-24 22:31:14.000 2013-04-24 22:31:23.000 142621
182 2013-04-24 22:35:55.000 2013-04-24 22:36:10.000 142661
31 2013-06-20 15:12:42.000 2013-06-20 15:13:39.000 142701
31 2013-06-20 15:20:08.000 2013-06-20 15:20:28.000 142741
31 2013-06-20 15:23:29.000 2013-06-20 15:23:45.000 142781
31 2013-06-20 15:26:39.000 2013-06-20 15:27:06.000 142821
31 2013-06-20 15:28:57.000 2013-06-20 15:29:44.000 142861
NULL 2013-04-24 22:37:50.000 2013-04-24 22:38:37.000 142901
NULL 2013-04-24 22:40:07.000 2013-04-24 22:41:41.000 142941
116 2013-04-24 22:45:09.000 2013-04-24 22:45:24.000 142981
187 2013-04-24 22:48:15.000 2013-04-24 22:48:24.000 143021
NULL 2013-04-24 22:54:57.000 2013-04-24 22:55:33.000 143061
NULL 2013-05-01 21:36:20.000 2013-05-01 21:37:44.000 143101
NULL 2013-05-01 21:39:56.000 2013-05-01 21:40:11.000 143141
NULL 2013-05-01 21:43:57.000 2013-05-01 21:46:34.000 143181
NULL 2013-05-01 21:49:29.000 2013-05-01 21:49:43.000 143221
NULL 2013-05-01 21:56:55.000 2013-05-01 21:57:26.000 143261
NULL 2013-05-01 22:03:51.000 2013-05-01 22:04:34.000 143301
85 2013-07-10 20:16:50.000 2013-07-10 20:16:52.000 143341
31 2013-07-10 20:19:46.000 2013-07-10 20:20:00.000 143381
31 2013-07-10 20:24:22.000 2013-07-10 20:25:03.000 143421
31 2013-07-10 20:26:23.000 2013-07-10 20:27:32.000 143461
31 2013-07-10 20:28:03.000 2013-07-10 20:28:51.000 143501
I really tried to understand your #ploto generation but couldn't. For example I didn't understand the join and what you are selecting and why would you want to get 0 when it is null (which means 1900/01/01). Also subtracting date times and casting to float is a hard to follow way of getting time as a day fraction.
From your description this is what I inferred:
WITH ploto
AS (SELECT AgentId,
CallEnd,
LEAD(CallStart) OVER (PARTITION BY agentId ORDER BY CallStart) AS nextCall
FROM #thuranin)
SELECT AgentId,
AVG(DATEDIFF(SECOND, CallEnd, nextCall)) AS average
FROM ploto
WHERE nextCall > CallEnd
AND DATEDIFF(HOUR, callEnd, nextCall) < 6
GROUP BY AgentID;
With your sample data set output is (in seconds):
AgentId Average
NULL 287
31 326
65 1764
116 826
166 225
169 416
175 808
182 594
191 1569
And here is SQLFiddle link.
EDIT: Some explanation. You didn't specify version so I assumed at least MS SQL 2012. There are CallStarts (and CallEnd) that overlap with the previous (AgentId NULL). I removed them from check. Also arbitrarily assumed if there is more than 6 hours between a CallEnd and next CallStart then I should think employee's work has ended and she\he is gone home, that one shouldn't count.

Would like to return a fake row if there is no match to my pair (for a year)

I would like to clean up some data returned from a query. This query :
select seriesId,
startDate,
reportingCountyId,
countyId,
countyName,
pocId,
pocValue
from someTable
where seriesId = 147
and pocid = 2
and countyId in (2033,2040)
order by startDate
usually returns 2 county matches for all years:
seriesId startDate reportingCountyId countyId countyName pocId pocValue
147 2004-01-01 00:00:00.000 6910 2040 CountyOne 2 828
147 2005-01-01 00:00:00.000 2998 2033 CountyTwo 2 4514
147 2005-01-01 00:00:00.000 3000 2040 CountyOne 2 2446
147 2006-01-01 00:00:00.000 3018 2033 CountyTwo 2 5675
147 2006-01-01 00:00:00.000 4754 2040 CountyOne 2 2265
147 2007-01-01 00:00:00.000 3894 2033 CountyTwo 2 6250
147 2007-01-01 00:00:00.000 3895 2040 CountyOne 2 2127
147 2008-01-01 00:00:00.000 4842 2033 CountyTwo 2 5696
147 2008-01-01 00:00:00.000 4846 2040 CountyOne 2 2013
147 2009-01-01 00:00:00.000 6786 2033 CountyTwo 2 2578
147 2009-01-01 00:00:00.000 6817 2040 CountyTwo 2 1933
147 2010-01-01 00:00:00.000 6871 2040 CountyOne 2 1799
147 2010-01-01 00:00:00.000 6872 2033 CountyTwo 2 4223
147 2011-01-01 00:00:00.000 8314 2033 CountyTwo 2 3596
147 2011-01-01 00:00:00.000 8315 2040 CountyOne 2 1559
But note please that the first entry has only CountyOne for 2004. I would like to return a fake row for CountyTwo for a graph I am doing. It would be sufficient to fill it like CountyOne only with pocValue = 0.
thanks!!!!!!!!
Try this (if you need blank row for that countryid)
; with CTE AS
(SELECT 2033 As CountryID UNION SELECT 2040),
CTE2 AS
(
seriesId, startDate, reportingCountyId,
countyId, countyName, pocId, pocValue
from someTable where
seriesId = 147 and pocid = 2 and countyId in (2033,2040)
order by startDate
)
SELECT x1.CountyId, x2.*, IsNull(pocValue,0) NewpocValue FROM CTE x
LEFT OUTER JOIN CTE2 x2 ON x1.CountyId = x2.reportingCountyId