Select one row per index value with max column value - sql

With a table setup with the following fields:
SKU, EVENTSTARTDATE, EVENTENDDATE, PRICE, (...etc...)
and housing thousands of rows here is example data (dates are YYMMDD, century code excluded):
1111111, 101224, 101231, 10.99
1111111, 110208, 110220, 9.99
1111111, 110301, 110331, 8.99
2222222, 101112, 101128, 15.99
2222222, 101201, 110102, 14.99
etc
I'd like to have a SELECT statement return one row per SKU with the maximum EVENTSTARTDATE without having a WHERE clause isolating a specific SKU or incomplete subset of SKUs (desired SELECT statement should return one row per SKU for all SKUs). I'd eventually like to add the criteria that start date is less than or equal to current date, and end date is greater than or equal to current date, but I have to start somewhere first.
Example results desired (for now just max date):
1111111, 110301, 110331, 8.99
2222222, 101201, 110102, 14.99
etc.

From recent versions of DB2, you can use the analytical function ROW_NUMBER()
SELECT *
FROM (
SELECT
tablename.*,
ROW_NUMBER() OVER (PARTITION BY sku
ORDER BY eventstartdate DESC) As RowNum
FROM tablename) X
WHERE X.RowNum=1
For each Partition (group of SKU), the data is row numbered following the order by eventstartdate desc, so 1,2,3,...starting from 1 for the latest EventStartDate. The WHERE clause then picks up only the latest per SKU.

Have a look at GROUP BY and HAVING clauses.
select sku, max(eventstartdate)
FROM TABLE
group by sku
having eventstartdate <= sysdate
Edit: added HAVING statement

other solution
select distinct f3.*
from yourtable f1
inner join lateral
(
select * from yourtable f2
where f1.SKU=f2.SKU
order by EVENTSTARTDATE desc, EVENTENDDATE desc
fetch first rows only
) f3 on 1=1

Related

how to show for every user the last two payement date and sum of mounts?

i have 2 tables where from i'm trying to extract from table 1 the last 2 taxe dates per user who were taxed for the last time on the 19/06/2022 and with product id 12 in table 2, and the sum amount of taxes, as well as the time range between the two last taxe dates as mentionned in the image bellow .
First step is to add a RANK() or ROW_NUMBER() to order the payments backwards, by id so you're only looking at the 2 last payments. Like this.
The next step is to aggregate those to get min and max dates, and sum of amount. Like this.
Lastly, you calculate the difference between min and max dates. Like this.
WITH LAST_TWO AS (
SELECT *,ROW_NUMBER() OVER(PARTITION BY id ORDER BY tax_date DESC) AS time_ago
FROM table1
QUALIFY time_ago <= 2
),
AGG AS (
SELECT
id,
MIN(tax_date) as tax_date_MIN,
MAX(tax_date) as tax_date_MAX,
SUM(amount) as amount_SUM
FROM LAST_TWO
GROUP BY id
)
SELECT id, amount_SUM, DATEDIFF(day, tax_date_MIN, tax_date_MAX) as DATE_RANGE
FROM AGG
INNER JOIN table2 ON AGG.id = table2.id
WHERE table2.product_id = 12;

How to get the latest 3 records of each group from dolphindb database?

My table name is trades, and its columns are permno, symbol, date, prc, shrout, ret, vol. I want to get the latest 3 records of each stock each date group. Does DolphinDB support such querying methods?
declare #trades as table
(
permno int,
symbol int,
groupdate date
)
insert into #trades(permno,symbol,groupdate)
values
(1,1,'2019-01-01'),
(2,2,'2019-01-01'),
(3,3,'2019-01-01'),
(4,4,'2019-01-01'),
(1,11,'2019-01-02'),
(2,22,'2019-01-02'),
(3,33,'2019-01-02'),
(4,44,'2019-01-02')
select * from(
select ROW_NUMBER() over(partition by groupdate order by groupdate)as rn,* from #trades)x
where rn <=3
In DolphinDB, one can use context-by clause to solve similar problems. For your question, use the code below:
select * from trades context by symbol, date limit -3
A negative value -3 for limit clause tells the system to get last 3 records for each symbol and date combination.

MAX() for 2 Dates Separately

I am trying to find a way to get the Max Date from one field and then to remove duplication get the Max of those dates from another field.
So far I have managed to get the Max of the Effective Dates, but need to get the Max timestamp from those values to remove duplication.
Here is what I have so far:
SELECT
a2.CUST_ID
, Address
, Effective_Date --DATE variable
, Timestamp_Entry --DATETIME variable
FROM
(SELECT
CUST_ID
, MAX (Effective_Date) as Most_Effective_Date
FROM Address_Table
GROUP BY CUST_ID) a1
JOIN Address_Table a2
ON a1.CUST_ID = a2.CUST_ID and a1.Most_Effective_Date = a2.Effective_Date
(Some timestamp entrys may be newer entries with older effective date, which is why the Effective Date takes priority, and then the TimeStamp should remove duplicates
I think this is what you want:
select a.*
from (select a.*,
row_number() over (partition by cust_id order by effective_date desc, timestamp_entry desc) as seqnum
from address_table a
) a
where seqnum = 1;
This returns the "most recent" address for each customer based on the two columns.

Finding max of transaction_date for corresponding code

I'm trying to find out how to find max of transaction_date per EAN_code
My table looks like:
Transaction_Date EAN_Code
09/04/2018 3029440000286
09/04/2018 3029440000286
08/04/2018 5000128221139
14/04/2018 5000128221139
08/04/2018 5000128221139
10/04/2018 5000128221108
Essentially what we need to do is for the list of items we want to pull out the latest date that it was sold across, e.g. one row per product, last date sold.
Both columns have non distinct values.
Simply do a GROUP BY. Use MAX() to get the latest date for each product.
select EAN_Code, max(Transaction_Date)
from tablename
group by EAN_Code
You could use ROW_NUMBER/RANK:
SELECT *
FROM (SELECT *,ROW_NUMBER() OVER(PARTITION BY Ean_Code
ORDER BY Transaction_Date DESC) AS rn
FROM table_name) s
WHERE s.rn = 1;

Return min date and corresponding amount to that distinct ID

Afternoon
I am trying to return the min value/ max values in SQL Server 2005 when I have multiple dates that are the same but the values in the Owed column are all different. I've already filtered the table down by my select statement into a temp table for a different query, when I've then tried to mirror I have all the duplicated dates that you can see below.
I now have a table that looks like:
ID| Date |Owes
-----------------
1 20110901 89
1 20110901 179
1 20110901 101
1 20110901 197
1 20110901 510
2 20111001 10
2 20111001 211
2 20111001 214
2 20111001 669
My current query:
Drop Table #Temp
Select Distinct Convert(Varchar(8), DateAdd(dd, Datediff(DD,0,DateDue),0),112)as Date
,ID
,Paid
Into #Temp
From Table
Where Paid <> '0'
Select ,Id
,Date
,Max(Owed)
,Min(Owed)
From #Temp
Group by ID, Date, Paid
Order By ID, Date, Paid
This doesn't strip out any of my dates that are the same, I'm new to SQL but I'm presuming its because my owed column has different values. I basically want to be able to pull back the first record as this will always be my minimum paid and my last record will always be my maximum owed to work out my total owed by ID.
I'm new to SQL so would like to understand what I've done wrong for my future knowledge of structuring queries?
Many Thanks
In your "select into"statement, you don't have an Owed column?
GROUP BY is the normal way you "strip out values that are the same". If you group by ID and Date, you will get one row in your result for each distinct pair of values in those two columns. Each row in the results represents ALL the rows in the underlying table, and aggregate functions like MIN, MAX, etc. can pull out values.
SELECT id, date, MAX(owes) as MaxOwes, MIN(owes) as minOwes
FROM myFavoriteTable
GROUP BY id, date
In SQL Server 2005 there are "windowing functions" that allow you to use aggregate functions on groups of records, without grouping. An example below. You will get one row for each row in the table:
SELECT id, date, owes,
MAX(Owes) over (PARTITION BY select, id) AS MaxOwes,
MIN(Owes) over (PARTITION BY select, id) AS MinOwes
FROM myfavoriteTable
If you name a column "MinOwes" it might sound like you're just fishing tho.
If you want to group by date you can't also group by ID, too, because ID is probably unique. Try:
Select ,Date
,Min(Owed) AS min_date
,Max(Owed) AS max_date
From #Temp
Group by Date
Order By Date
To get additional values from the row (your question is a bit vague there), you could utilize window functions:
SELECT DISTINCT
,Date
,first_value(ID) OVER (PARTITION BY Date ORDER BY Owed) AS min_owed_ID
,last_value(ID) OVER (PARTITION BY Date ORDER BY Owed) AS max_owed_ID
,first_value(Owed) OVER (PARTITION BY Date ORDER BY Owed) AS min_owed
,last_value(Owed) OVER (PARTITION BY Date ORDER BY Owed) AS max_owed
FROM #Temp
ORDER BY Date;