/ / T-SQL verifica iterativamente el patrón histórico - tsql, iteración

T-SQL verifica iterativamente el patrón de historial - tsql, iteración

¿Cómo hacer una selección basada en el historial anterior de un artículo?

Por ejemplo, estoy tratando de seleccionar un elemento quetiene un valor de 1, anteriormente tenía un valor de 10 y anteriormente tenía un valor de 1. El único itemId que debe satisfacer los datos a continuación sería itemId = 3.

    WITH Items (itemId, date, val) AS (
SELECT 1, CONVERT(datetime, "5/1/2011"), 6 UNION ALL
SELECT 2, CONVERT(datetime, "5/1/2011"), 5 UNION ALL
SELECT 3, CONVERT(datetime, "5/1/2011"), 1 UNION ALL
SELECT 1, CONVERT(datetime, "6/1/2011"), 1 UNION ALL
SELECT 2, CONVERT(datetime, "6/1/2011"), 10 UNION ALL
SELECT 3, CONVERT(datetime, "6/1/2011"), 10 UNION ALL
SELECT 1, CONVERT(datetime, "7/1/2011"), 1 UNION ALL
SELECT 2, CONVERT(datetime, "7/1/2011"), 1 UNION ALL
SELECT 3, CONVERT(datetime, "7/1/2011"), 1
)
select distinct itemId from Items where val = 1
--and a previous date val = 10
--and a previous previous date val = 1

Respuestas

0 para la respuesta № 1

Ya que tienes la Valor en fecha anterior requisito, tienes que usar un ROW_NUM Ordenar por el ItemId y la Fecha.

Entonces haces un dos auto se une en Id más el RowNum se une al anterior (vigente a la fecha anterior), y agregue el WHERE cláusulas al 1-10-1

WITH Items_Original (itemId, date, val) AS
(
SELECT 1, CONVERT(datetime, "5/1/2011"), 6 UNION ALL
SELECT 2, CONVERT(datetime, "5/1/2011"), 5 UNION ALL
SELECT 3, CONVERT(datetime, "5/1/2011"), 1 UNION ALL
SELECT 1, CONVERT(datetime, "6/1/2011"), 1 UNION ALL
SELECT 2, CONVERT(datetime, "6/1/2011"), 10 UNION ALL
SELECT 3, CONVERT(datetime, "6/1/2011"), 10 UNION ALL
SELECT 1, CONVERT(datetime, "7/1/2011"), 1 UNION ALL
SELECT 2, CONVERT(datetime, "7/1/2011"), 1 UNION ALL
SELECT 3, CONVERT(datetime, "7/1/2011"), 1
),
Items As
(
Select
ROW_NUMBER() OVER(ORDER BY ItemId, Date) AS RowNum, *
FROM Items_Original
)
select *
from Items I1
Inner JOIN Items I2
On I1.itemId = I2.itemId
And I1.RowNum = I2.RowNum-1
Inner JOIN Items I3
On I2.itemId = I3.itemId
And I2.RowNum = I3.RowNum-1
Where 1=1
And I1.val = 1
And I2.val = 10
And I3.val = 1

0 para la respuesta № 2

Esto obtendrá la respuesta específica que desees. Sin embargo, no estoy seguro de qué tan útil sea. Sin embargo, ¿siempre vas a estar buscando artículos que tengan exactamente 3 valores, 1-10-1?

SELECT
A.itemID
FROM
Items A
INNER JOIN Items B ON A.itemID = B.itemID AND B.val = 10
INNER JOIN Items C ON B.itemID = C.itemID AND C.val = 1
WHERE
A.val = 1

0 para la respuesta № 3
 WITH Items (itemId, date, val) AS (
SELECT 1, CONVERT(datetime, "5/1/2011"), 6 UNION ALL
SELECT 2, CONVERT(datetime, "5/1/2011"), 5 UNION ALL
SELECT 3, CONVERT(datetime, "5/1/2011"), 1 UNION ALL
SELECT 1, CONVERT(datetime, "6/1/2011"), 1 UNION ALL
SELECT 2, CONVERT(datetime, "6/1/2011"), 10 UNION ALL
SELECT 3, CONVERT(datetime, "6/1/2011"), 10 UNION ALL
SELECT 1, CONVERT(datetime, "7/1/2011"), 1 UNION ALL
SELECT 2, CONVERT(datetime, "7/1/2011"), 1 UNION ALL
SELECT 3, CONVERT(datetime, "7/1/2011"), 1
),
cte as
(
select *, row_number() over(partition by itemId order by date) [rn]
from Items t
)

select distinct a.itemId
from cte a
join cte b on b.rn = a.rn + 1 and b.itemId = a.itemId
join cte c on c.rn = b.rn + 1 and c.itemId = a.itemId
where a.val = 1 and b.val = 10 and c.val = 1