SQL where function used with Over Partition - sql

I am calculation a range of figures, one of the calculated columns are a weighted average calculation based on "Accountlink" by "DTstamp".
The problem is that I need the final result (per accountlink) to show in a new column - each Accountlink's final result per accountlink - to be used in a new calculation - as per example below:
Accountlink WA_Calc WA_Calc_Final
1 20.00 30.00
1 40.00 30.00
1 30.00 30.00
2 15.00 20.00
2 35.00 20.00
2 28.00 20.00
on the image is an extract of the script I am compiling.
However, I am just getting errors.
Any assistance and/or direction will be much appreciated.

You need a column that specifies the ordering. SQL tables represent unordered sets, so there is no "last row", unless a column specifies that.
Let me assume you have one. I'll just call it ?.
Then you can use first_value():
select t.*,
first_value(wa_calc) over (partition by id order by ? desc) as wa_calc_final
from t;

Related

Pandas multi index/groupby

I have a data frame containing several registers from sold products, revenues, prices and dates
DATA CLIENT PRODUCT PRICE
2020-08-28 xxxxxxx RIOT 20.0
I am to group my information by year/month and product. I am running a group by to_period that extract the exactly information :
dfgmv = dfgift[['PRODUCT','PRICE']].groupby([dfgift.DATA.dt.to_period("M"), 'PRODUCT']).agg(['count','sum'])
This is the output :
PRICE
count sum
DATA PRODUCT
2020-08 RIOT 2 40.00
The question is that, as I export to excel, the date column is not interpreted as da date (yyyy-mm). I am trying to convert the yyyy-mm to something like yyyy-mm-dd so Excel understand it.
I´ve read several questions about multi index but my knowledge wasn't enough to use that info to apply here. I tried to change my index to datetime, but, as I run it, I lost the second index column (product).
dfgmv.index = pd.to_datetime(dfgmv.index.get_level_values(0).astype('datetime64[ns]'))
.
VALOR
count sum
DATA
2020-08-01 2 40.00
So, How can I change the information format without losing my index?
Index.set_levels is designed to allow for the setting of specific index level(s).
dfgmv.index = (
dfgmv.index.set_levels(dfgmv.index.levels[0].astype('datetime64[ns]'), level=0)
)
Result
PRICE
count sum
DATA PRODUCT
2020-08-01 RIOT 1 20.0
You can change your groupby to include start of month for each date you have:
dfgmv = dfgift[['PRODUCT','PRICE']].groupby([dfgift.DATA.astype('datetime64[M]'), 'PRODUCT']).agg(['count','sum'])
dfgmv
PRICE
count sum
DATA PRODUCT
2020-08-01 RIOT 1 20.0

Format table with SQL to put multiple entry on one row

I'm currently working on an Access database, and I would like to make a query that can fuse multiple rows into one, but keeping all the entries separated in differents columns.
The table i'm making my query on is called "Monthly", is used for monthly reports of activity and is made this way:
project
date
turnover
margin
0001
01/01/2021
10000
20%
0001
01/02/2021
10500
15%
0002
01/01/2021
8500
25%
I would like to know if there is a way to transform it into this:
project
date
turnover
margin
date
turnover
margin
0001
01/01/2021
10000
20%
01/02/2021
10500
15%
0002
01/01/2021
8500
25%
01/02/2021
I first thought of using GROUP BY, but it's clearly not adapted.
The objective would be to format it on a SQL request, not to modify the structure/ how the data is stored.
Thanks in advance for anyone who answers.
If it doesn't already exist, add an autonumber field to table.
Consider:
Query1:
SELECT ID, project, [date] AS Data, "D" AS Cat FROM ProjectData
UNION SELECT ID, project, turnover, "T" FROM ProjectData
UNION SELECT ID, project, margin, "M" FROM ProjectData;
Query2:
TRANSFORM First(Query1.Data) AS FirstOfData
SELECT Query1.project
FROM Query1
GROUP BY Query1.project
PIVOT DCount("*","ProjectData","Project='" & [Project] & "' AND ID<" & [ID])+1 & [Cat];
Presume this will be a multi-year db so probably need some filter criteria to limit selection to one year.
Similar example Pivot Query in MS Access
For more about CROSSTAB queries, review http://allenbrowne.com/ser-67.html
Or emulate CROSSTAB (example for 2 months):
SELECT ProjectData.project,
Max(IIf(Month([date])=1,[Date],Null)) AS Jan, Max(IIf(Month([date])=1,[Margin],Null)) AS JanMargin, Max(IIf(Month([date])=1,[turnover],Null)) AS JanTurnover,
Max(IIf(Month([date])=2,[Date],Null)) AS Feb, Max(IIf(Month([date])=2,[Margin],Null)) AS FebMargin, Max(IIf(Month([date])=2,[turnover],Null)) AS FebTurnover
FROM ProjectData
GROUP BY ProjectData.project;
Should not use reserved words as names. Date is a reserved word.

How to count and categorize values by the same criteria

I have a table in SQL Server with just 2 columns, the ProductID and the Discount.
There are many products registered in rows.
So, I want to know how many products there are in this table with the same discount, categorized by the discount column value.
How can I query this by the easiest and simplest way?
The view that I expect for:
Discount - QTD
-------------------
0.25 - 150
0.40 - 320
0.75 - 532
It seems like a simple aggregation should do the trick.
Select Discount
,QTD = count(*)
From YourTable
Group By Discount

How to negate records

I have an assignment where I'm supposed to figure out how many parts a person bought in a certain month. Each record comes from an invoice with part orders.
The important parts of the table are:
Orders (PartNo, Quantity, Price, discount, EXP_Price, date)
the data would looks like this:
P1 1 30.00 15.00 15.00 11-NOV-06
P2 1 30.00 6.00 24.00 19-NOV-06
P2 -2 30.00 0.00 -30.00 11-NOV-06
P2 2 30.00 0.00 30.00 20-NOV-06
The issue I'm having is with the last two lines. The last two orders cancel each other out, as if someone rang the last part in error and had to cancel it out of the final bill.
How does someone construct a query that account for the fact that the last two rows negate each other?
Thanks in advance
OK I've been trying this and iteraction around it
select PartNo
from Practice
Where PARTNO = (
select PARTNO , SUM(Quantity)
from Practice
group by PARTNO);
The questions just states how many parts did Joe Smith (the name that corresponds to this invoice) buy in the month of November(sorry not mouth) of November. Know this guy he will want us to account for the fact that Joe never actually bought those parts since they were never charged to the buyer.
It looks very simple, you just need to sum all columns multiplied to the sign of quantity.
select PartNo, sum(Quantity) as Quantity, sum(Price*sign(Quantity)) as Price, sum(discount*sign(Quantity)) as discount, sum(EXP_Price*sign(Quantity)) as EXP_Price
from Orders
group by PartNo

How to update running balance in one shot?

I have a temp table, let's call it #invoices, defined as
create table (id int identity(1, 1), billed money, credited money, balance money)
i have the following data in it
Billed Credited
140.00
20.00
60.00
20.00
-20.00
I would like to update the balance column with the running balance. so that the Balance column is updated properly. Balance is basically, Billed - Credited, but has to take into the account the previous row.
So in my example, the Balance will be so:
Billed Credited Balance
140.00 140.00
20.00 160.00
60.00 100.00
20.00 80.00
-20.00 -100.00
Is there a way to do this without looping through the rows and keeping the running balance? Basically I am looking to update the Balance column in a set-based way.
There are set-based ways to calculate running totals in SQL Server, however in the current versions of SQL Server a cursor-based solution is often quicker.
Adam Machanic wrote a great article on it here.
The answer is triggers. I use them, and it works beautifully. I don't have exactly your setup (it's slightly strange, if I may say), but in general, they are the correct approach here. You will need to be mindful of ordering, but other than that, it should be fine.