Home > Enterprise >  Get the first date from the latest repeated group
Get the first date from the latest repeated group

Time:10-05

I'm trying to creare a SQL Server query (without LOOPING) for the following:

I need to get latest inserted [Price] and [PriceDate] from a table [Prices] but with the following condition> if the price "before the latest", and "the latest" are the same, return the "before the latest" until the previous price is not the same anymore.

Example:

ID AssetID PriceDate Price
1 19969 8/31/2022 1.89
2 19969 7/31/2022 1.89
3 19969 6/30/2022 1.89
4 19969 5/31/2022 1.89
5 19969 4/30/2022 1
6 19969 3/31/2022 1
7 19969 2/28/2022 1
8 19969 1/31/2022 1
9 19969 1/3/2022 1.89
10 19969 12/31/2021 1.89

So for this example, it should return ID 4, PriceDate 5/31/2022. The latest entry is 8/31/2022, but since the price before (7/31/2022) is 1.89 I need to get this one, and since the one before (6/30/2022) is still 1.89, I need to keep looking back, until the previous entry (PriceDate) has a different price (4/30/2022).

Note that for 1/3/2022 the price is 1.89 again, however I don't care about this date since it belong to a different sequential group.

I would do it with a loop, but since this table has thousands of thousands of records for different AssetIDs, I didn't want to take this approach.

This what I got so far, but it not returning the right date by AssetID.

SELECT AssetID, price, PRICEDATE,
     FIRST_VALUE(PriceDate) OVER (
        PARTITION BY Price ORDER BY PriceDate 
        ) AS LastValue
FROM PricesSELECT AssetID, price, PRICEDATE,
     FIRST_VALUE(PriceDate) OVER (
        PARTITION BY Price ORDER BY PriceDate 
        ) AS LastValue
FROM Prices

Thanks for the help

CodePudding user response:

This will return id 4 and 8, because those are the id's where a price change did occur.

select *
from (
   SELECT 
      id, 
      PriceDate, 
      price, 
      lead(price) over (order by id) previousprice
   from prices 
) x
where price<>previousprice

see: DBFIDDLE

output:

id PriceDate price previousprice
4 2022-05-31 1.89 1.00
8 2022-01-31 1.00 1.89

CodePudding user response:

You'll want them separated by AssetID too.

DROP TABLE IF EXISTS #P;

CREATE TABLE #P
(ID INT IDENTITY PRIMARY KEY,
AssetID INT,
PriceDate DATE,
Price Money);

INSERT INTO #P
(
AssetID,
PriceDate,
Price)
VALUES
(
19969,
'2022-08-31',
1.89
),
(
19969,
'2022-07-31',
1.89
),
(
19969,
'2022-06-30',
1.89
),
(
19969,
'2022-05-31',
1.89
),
(
19969,
'2022-04-30',
1.0
),
(
19969,
'2022-03-31',
1.0
),
(
19969,
'2022-02-28',
1.0
),
(
19969,
'2022-01-31',
1.0
),
(
19969,
'2022-01-03',
1.89
),
(
19969,
'2021-12-31',
1.89
);

SELECT * FROM #P;

WITH cte AS
(
    SELECT 
        ID,
        AssetID,
        PriceDate,
        Price,
        LEAD(Price) OVER (PARTITION BY AssetID ORDER BY AssetID, PriceDate DESC) AS PreviousPrice
    FROM
        #P
)
SELECT * FROM cte 
WHERE PreviousPrice <> Price OR PreviousPrice IS NULL
ORDER BY PriceDate DESC;
  • Related