I have a table in snowflake and I want to see the results for the max date and 2nd to Max date. I wrote a query below which gives the results for max date
SELECT MAX(FILE_DATE) "MAX_DATE"
,UPPER(RETAIL) "SHOP"
FROM PRODUCTS
GROUP BY UPPER(RETAIL)
the results are something like this
MAX_DATE SHOP
2022-09-27 SHOP1
2022-08-01 SHOP2
I am looking for
2nd_MAX_DATE MAX_DATE SHOP
2022-08-27 2022-09-27 SHOP1
2022-07-01 2022-08-01 SHOP2
I tried something with where clause WHERE FILE_DATE < ( SELECT MAX(FILE_DATE) FROM "PRODUCTS" GROUP BY UPPER(RETAILER)) but this isn't working
One way is to use a cross join.
Here's a full sample roughly altered to your schema using SQL Server syntax.
CREATE TABLE Products (
Id INT PRIMARY KEY,
Retail VARCHAR(100),
FileDate DATETIME
);
INSERT INTO Products (Id, Retail, FileDate)
VALUES (1, 'shop 1', '2022-09-01'),
(2, 'shop 1', '2022-09-01'),
(3, 'shop 1', '2022-09-01'),
(4, 'shop 2', '2022-09-01'),
(5, 'shop 2', '2022-09-01'),
(6, 'shop 2', '2022-09-30'),
(7, 'shop 3', '2022-09-01'),
(8, 'shop 3', '2022-09-01'),
(9, 'shop 3', '2022-09-20');
SELECT DISTINCT
MAX(p1.FileDate) "MAX_DATE",
UPPER(p1.Retail) "SHOP"
FROM Products p1
CROSS JOIN Products p2
WHERE
p1.FileDate > p2.FileDate
GROUP BY
p1.Retail,
p2.Retail
Output
2022-09-30|SHOP 2
2022-09-20|SHOP 3
As you want the latest two file_dates for every shop, you can use WINDOW function
WITH CTE as(
SELECT FILE_DATE
,UPPER(RETAIL) "SHOP"
, ROW_NUMBER() OVER(PARTITION BY UPPER(RETAIL) ORDER BY FILE_DATE DESC) rn
FROM PRODUCTS
)
SELECT "SHOP",MIN(FILE_DATE) second_date, MAX(FILE_DATE) first_date
FROM CTE
WHERE rn < 3
GROUP BY "SHOP"
create or replace TABLE SNOWPARK_QUICKSTART.TELCO.Products ( ID INT, FileDate TIMESTAMP, Retail VARCHAR(16777216) );
INSERT INTO Products (Id, Retail, FileDate)
VALUES (1, 'shop 1', '2022-09-01'),
(2, 'shop 1', '2022-09-01'),
(3, 'shop 1', '2022-09-01'),
(4, 'shop 2', '2022-09-01'),
(5, 'shop 2', '2022-09-01'),
(6, 'shop 2', '2022-09-30'),
(7, 'shop 3', '2022-09-01'),
(8, 'shop 3', '2022-09-01'),
(9, 'shop 3', '2022-09-20');
SELECT RETAIL
,FILEDATE
,IFF(RANK()OVER(PARTITION BY RETAIL ORDER BY FILEDATE DESC)=2,'SECOND MAX DATE','MAX DATE') DAY_DESC
FROM
Products
GROUP BY
RETAIL,FILEDATE
QUALIFY
RANK()OVER(PARTITION BY RETAIL ORDER BY FILEDATE DESC)<3
Using the data provided PeteGo as a CTE:
with Products (Id, Retail, FileDate) as
(
select * from values
(1, 'shop 1', '2022-09-01'::date),
(2, 'shop 1', '2022-09-01'::date),
(3, 'shop 1', '2022-09-01'::date),
(4, 'shop 2', '2022-09-01'::date),
(5, 'shop 2', '2022-09-01'::date),
(6, 'shop 2', '2022-09-30'::date),
(7, 'shop 3', '2022-09-01'::date),
(8, 'shop 3', '2022-09-01'::date),
(9, 'shop 3', '2022-09-20'::date)
)
you can use the window function NTH_VALUE and then combine with DISTINCT to de-dup:
select distinct
Retail
,nth_value(FileDate, 1) over(partition by retail order by filedate desc) as "1st_MAX_DATE"
,nth_value(FileDate, 2) over(partition by retail order by filedate desc) as "2nd_MAX_DATE"
from products
gives:
RETAIL | 1st_MAX_DATE | 2nd_MAX_DATE |
---|---|---|
shop 1 | 2022-09-01 | 2022-09-01 |
shop 2 | 2022-09-30 | 2022-09-01 |
shop 3 | 2022-09-20 | 2022-09-01 |
But you can see the two values of 2022-09-01
for shop 1
are getting picked.
and can be shown if you also pick the id's:
select distinct
Retail
,nth_value(FileDate, 1) over(partition by retail order by filedate, id desc) as "1st_MAX_DATE"
,nth_value(FileDate, 2) over(partition by retail order by filedate, id desc) as "2nd_MAX_DATE"
,nth_value(id, 1) over(partition by retail order by filedate, id desc) as "1st_id"
,nth_value(id, 2) over(partition by retail order by filedate, id desc) as "2nd_id"
from products
RETAIL | 1st_MAX_DATE | 2nd_MAX_DATE | 1st_id | 2nd_id |
---|---|---|---|---|
shop 1 | 2022-09-01 | 2022-09-01 | 3 | 2 |
shop 2 | 2022-09-01 | 2022-09-01 | 5 | 4 |
shop 3 | 2022-09-01 | 2022-09-01 | 8 | 7 |
you can therefore de-dup the shops/dates:
select distinct
Retail
,nth_value(FileDate, 1) over(partition by retail order by filedate desc) as "1st_MAX_DATE"
,nth_value(FileDate, 2) over(partition by retail order by filedate desc) as "2nd_MAX_DATE"
from (
select distinct Retail, FileDate from products
)
now gives a null
as I originally expected:
RETAIL | 1st_MAX_DATE | 2nd_MAX_DATE |
---|---|---|
shop 1 | 2022-09-01 | null |
shop 2 | 2022-09-30 | 2022-09-01 |
shop 3 | 2022-09-20 | 2022-09-01 |
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.