SQL Group by balance - sql

I have a table like below:
I want the results to be like below which fetch the start and end of the balance but we can't use group by as balance should be grouped only based on consecutive groups. can you please help me with this ?:

There is most certainly a duplicate of this question, however, it is easier to crank out an answer than to search. These types of problems, data in the order inserted or shown with no order indicator, can simply be solved by two derivative queries. The first to use LAG or LEAD to check for gaps and the second to sum up the changes which are represented by a value of 1 as opposed to 0. The key here, using MSSQL Server, is SUM(x) OVER (ORDER BY Date ROWS UNBOUNDED PRECEDING).
DECLARE #T TABLE(balance INT, date DATETIME)
INSERT #T VALUES
(36,'1/1/2020'),
(36,'1/2/2020'),
(36,'1/3/2020'),
(24,'1/4/2020'),
(24,'1/5/2020'),
(36,'1/6/2020'),
(36,'1/7/2020'),
(37,'1/8/2020'),
(38,'1/9/2020')
;WITH GapsMarked AS
(
--If the prev value by date (by natural order of data above) does not equal this value mark it as a boundry
SELECT *,
IsBoundry = CASE WHEN ISNULL(LAG(balance) OVER (ORDER BY date),balance) = balance THEN 0 ELSE 1 END
FROM #T
)
,VirtualGroup AS
(
SELECT
*,
--This serialzes the marked groups into seequntial clusters
IslandsMarked = SUM(IsBoundry) OVER (ORDER BY Date ROWS UNBOUNDED PRECEDING)
FROM
GapsMarked
)
SELECT
MAX(balance) AS balance,
MIN(date) AS start,
MAX(date) AS [end]
FROM
VirtualGroup
GROUP BY
IslandsMarked

select balance, min(start), max(end) from table where balance is in (
select balance from table
group by balance)
Hope it will help you

Related

Sum amount group by id in temporary table

This is my code:
SELECT ROW_NUMBER()OVER(order by date) as rowNo, id, amount
INTO #temptbl
FROM sales
WHERE code = 1000
I'm trying to group this temporary table and sum the amount by its id so the id will be unique.
*The row column is mandatory because it will be used later.
I've tried few ways like this,
SELECT ROW_NUMBER()OVER(order by date) as rowNo, id, amount
INTO #temptbl
FROM sales
WHERE code = 1000
GROUP BY id
and even tried subquey nad nesting but it wont work. I know the solution must be simple its just i cant see it yet. Thank you
You can use SUM with Partition BY like this:
SELECT ROW_NUMBER()OVER(order by date) as rowNo, id,
Sum(amount) over (partition by id) sumAmount
FROM sales
WHERE code = 1000
As you know, since you want the Row number then sum amount will be repeated for same ids

SQL Server: loop once a month value to the whole month

I have a table that gets one value of only one day in each month. I want to duplicate that value to the whole month until a new value shows up. the result will be a table with data for each day of the month based on the last known value.
Can someone help me writing this query?
This is untested, due to a lack of consumable sample data, but this looks like a gaps and island problem. Here you can count the number of non-NULL values for Yield to assign the group "number" and then get the windowed MAX in the outer SELECT:
WITH CTE AS(
SELECT Yield,
[Date],
COUNT(yield) OVER (ORDER BY [Date]) AS Grp
FROM dbo.YourTable)
SELECT MAX(yield) OVER (PARTITION BY grp) AS yield
[Date],
DATENAME(WEEKDAY,[Date]) AS [Day]
FROM CTE;
You seem to have data on the first of the month. That suggests an alternative approach:
select t.*, t2.yield as imputed_yield
from t cross apply
(select t2.*
from t t2
where t2.date = datefromparts(year(t.date), month(t.date), 1)
) t2;
This should be able to take advantage of an index on (date, yield). And it does assume that the value you want is on the first date of the month.

Teradata SQL -Min Max transaction dates from Rows

Tried Qualify row_Number () and Qualify Min & Max functions but still not able to get range of dates for transaction. See data structure below
Need help for the following output
Thank you in advance
You need to find the groups of consecutive dates first. There are several ways to do this, in your case the best should is based on comparing a sequence to another sequence with gaps in it:
with cte as
(
select t.*
-- consecutive numbers = sequence without gaps
,row_number()
over (partition by location, cust#, cust_type -- ??
order by transaction_date) as rn
-- consecutive numbers as long as there's no missing date = sequence with gaps
,(transaction_date - date '0001-01-01') as rn2
-- assign a common (but meaningless) value to consecutive dates,
-- value changes when there's a gap
,rn2 - rn as grp
from tab as t
)
select location, cust#, cust_type -- ??
,min(transaction_date), max(transaction_date)
,min(amount), max(amount)
from cte
-- add the calculated "grp" to GROUP BY
group by location, cust#, cust_type, grp
The columns used for PARTITION BY/GROUP BY depend on your rules.

selecting max value from table with two variable colums (microsoft SQL)

i´m working with a table that looks like this:
Start
https://i.stack.imgur.com/uibc3.png
My desired result would look like this:
Result
https://i.stack.imgur.com/v0sic.png
So i´m triyng to select the max value from two "combined" colums. If the values are the same amount (Part C), the outcome doesn't matter.
I tried to order the table by max value and then using distinct but the result didn't turn out as expected
Could you please offer a solution or some insight to this? Thanks in advance!
Use row_number():
select *
from (
select t.*, row_number() over(partition by part order by amount desc, zone) rn
from mytable t
) t
where rn = 1
For each part, this gives you the row with the highest amount; if there are top ties, column zone is used to break them.
If you want to allow ties, then use rank() instead, like:
rank() over(partition by part order by amount desc) rn
You can achieve this by using SUB Query
DECLARE #T TABLE(
PART VARCHAR(50),
ZONE VARCHAR(10),
Amt INT)
Insert Into #T Values ('PartA','71H',1),('PartA','75H',2),('PartB','98D',1),('PartB','98A',3),('PartC','75H',1),('PartC','52H',1)
SELECT M.PART,MIN(M.Zone) AS ZONE,S.AMOUNT
FROM #T M
INNER JOIN (
SELECT Part,MAX(Amt) as AMOUNT From #T
GROUP BY PART) S ON S.AMOUNT=M.Amt AND S.PART=M.PART
GROUP BY M.PART,S.AMOUNT
ORDER BY M.PART

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.