Calculated Year in Group by - hana-sql-script

I am working on ABAP CDS view and stuck somewhere, actually i have date and amount field and i have to show sum of amount year wise, but when i run below query it didnt group by on year and show year multiple time
#AbapCatalog.sqlViewName: 'ZTEST'
#AbapCatalog.compiler.compareFilter: true
#AccessControl.authorizationCheck: #CHECK
#EndUserText.label: 'Sales Cash Flow Report'
#VDM.viewType: #CONSUMPTION
#Analytics.dataCategory: #CUBE
define view ZRESV07 as select from vicdcfpay as PAY
{
left(PAY.dfaell,4) as Year
sum(PAY.bkond) as Amount
}
group by PAY.dfaell

Your original query will show output rows that you will think as duplicates.
This is because your GROUP BY clause is based on dfaell which includes the date, month and year data as well.
So your query will show aggrageted sums for each day identified with dfaell.
You need to modify dfaell with LEFT(dfaell,4)
In SQL you can manage your requirement as follows
select
LEFT(dfaell,4) as Year,
SUM(bkond) as Amount,
swhrkond
from vicdcfpay
group by
LEFT(dfaell,4),
swhrkond
Of course you can ommit swhrkond both from Select list and from Group By list at the same time, but since it is a reference field from bkond, it is good to keep it in the output result too.
But what I experienced with CDS view is that, it does not allow LEFT() function in the GROUP BY clause
So I what I can suggest you as a solution
Create two CDS views
In first one, you can use following SQL query
select
LEFT(dfaell,4) as YearErdat,
bkond,
swhrkond
from vicdcfpay as PAY
In the second query, reference this CDS and use GROUP BY clause
select
YearErdat,
sum(bkond) as Amount,
swhrkond
from ZCDSVIEW1
group by YearErdat, swhrkond

You are grouping by day, you should group by the year, instead. Like:
#AbapCatalog.sqlViewName: 'ZTEST'
#AbapCatalog.compiler.compareFilter: true
#AccessControl.authorizationCheck: #CHECK
#EndUserText.label: 'Sales Cash Flow Report'
#VDM.viewType: #CONSUMPTION
#Analytics.dataCategory: #CUBE
define view ZRESV07 as select from vicdcfpay as PAY
{
left(PAY.dfaell,4) as dfaell
sum(PAY.bkond) as Amount
}
group by dfaell

Related

Selecting another column from a query with a different date filter

I am working with some sales data and pulling the metrics for a particular week I am defining in the filter.
However, I want to add another column (first_sale_date) to my query. This will show the first time this asin/mp combo shows up in my table regardless of the date filter I am trying to pull the other metrics for.
Because I am already
filtering by date I don't know how to look back to all of the data in the table to find it's first appearance as it is before the week I am filtering for.
select date,
,asin
,marketplace
,SUM(ordered_product_sales) as OPS
,SUM(cogs) as cogs
**,min(date) as first_sale_date**
from prod.sales
where date > '2023-01-01'
group by 1,2,3,4
you can use a correlated subquery for this
select year
,week
,asin
,marketplace
,SUM(ordered_product_sales) as OPS
,SUM(cogs) as cogs
,( SELECT MIN(date) FROM sales sal1 WHERe sal1.asin = sal.asin and sal1.marketplace = sal.marketplace) as first_sale_date
from prod.sales sal
where year = '2023' and week = '1'
group by 1,2,3,4

Returning single records per month

I have a use case function that needs to returns a single row only for every end of month.
I tried using select distinct and it is showing multiple records for the same end of month
SELECT DISTINCT CASE
WHEN eff_interest_balance < 0.01 THEN trial_balance_date
WHEN date_paid < trial_balance_date THEN date_paid
END as A
, period
FROM dbo.Intpayments[enter image description here][1]
WHERE loan_number = 60023
ORDER BY period ASC
Each row should return single date for each month
Distinct is returning unique rows, not grouping them. You are looking to aggregate rows. This means using some combination of aggregate functions and group by.
What your current query is missing is some sort of logic for aggregating the rows that are in the same period. Do you want to compare the sum of these values? The min, the max?
In any case, the basic idea of aggregating and grouping would look like this - I don't think this summing is what you want, but the query shows the basic idea of aggregating and grouping:
SELECT
period
, SUM(eff_interest_balance) AS SumOfBalance
FROM dbo.Intpayments
WHERE loan_number = 60023
GROUP BY period

SQL-How to Sum Data of Clients Over Time?

Goal: SUM/AVG Client Data over multiple dates/transactions.
Detailed Question: How do I properly Group clients ('PlayerID') then SUM the int(MinsPlayed), then AVG (AvgBet)?
Current Issue: my Results are giving individual transactions day by day over the 90 day time period instead of the SUM/AVG over the 90 days.
Current Script/Results: FirstName-Riley is showing each individual daily transaction instead of 1 total SUM/AVG over set time period
Firstly, you don't need to use DISTINCT as you are going to be aggregating the results using GROUP BY, so you can take that out.
The reason you are returning a row for each transaction is that your GROUP BY clause includes the column you are trying to aggregate (e.g. TimePlayed). Typically, you only want to GROUP BY the columns that are not being aggregated, so remove all the columns from the GROUP BY clause that you are aggregating using SUM or AVG (TimePlayed, PlayerSkill etc.).
Here's your current SQL:
SELECT DISTINCT CDS_StatDetail.PlayerID,
StatType,
FirstName,
LastName,
Email,
SUM(TimePlayed)/60 AS MinsPlayed,
SUM(CashIn) AS AvgBet,
SUM(PlayerSkill) AS AvgSkillRating,
SUM(PlayerSpeed) AS Speed,
CustomFlag1
FROM CDS_Player INNER JOIN CDS_StatDetail
ON CDS_Player.Player_ID = CDS_StatDetail.PlayerID
WHERE StatType='PIT' AND CDS_StatDetail.GamingDate >= '1/02/17' and CDS_StatDetail.GamingDate <= '4/02/2017' AND CustomFlag1='N'
GROUP BY CDS_StatDetail.PlayerID, StatType, FirstName, LastName, Email, TimePlayed, CashIn, PlayerSkill, PlayerSpeed, CustomFlag1
ORDER BY CDS_StatDetail.PlayerID
You want something like:
SELECT CDS_StatDetail.PlayerID,
SUM(TimePlayed)/60 AS MinsPlayed,
AVG(CashIn) AS AvgBet,
AVG(PlayerSkill) AS AvgSkillRating,
SUM(PlayerSpeed) AS Speed,
FROM CDS_Player INNER JOIN CDS_StatDetail
ON CDS_Player.Player_ID = CDS_StatDetail.PlayerID
WHERE StatType='PIT' AND CDS_StatDetail.GamingDate BETWEEN '2017-01-02' AND '2017-04-02' AND CustomFlag1='N'
GROUP BY CDS_StatDetail.PlayerID
Next time, please copy and paste your text, not just linking to a screenshot.

calculating month salary for an employee

I am working on my Database in MS Access 2010
and i Need to build a query to Calculate the month salary for each Employee
it goes like this :
Input from user , which Year
Input from user again , which Month
Show Every Employee's Salary for the Input date
There are 2 Tables in the Query : Shifts , Employees
Shifts has a field for EmployeeID and a field for Day
Day field format is : Short Date
The problem is i don't know how to access the Month and the Year only !
I know that this is completely wrong , but i wanna do something like this:
SELECT
FROM EmployeesTBL INNER JOIN ShiftsTBL ON EmployeesTBL.EmployeeID = ShiftsTBL.EmployeeID
WHERE
Year(ShiftsTBL.Day)=[Enter Year]
AND
Month(ShiftsTBL.Day)=[Enter Month]
;
What do i need to write after SELECT to get the Sum of all Shifts and divide it by number of days the emp worked
Note : in the Shifts Table , i have EntryDate and ExitDate for every shift
Access has a bunch of built in date functions. I believe Month(date) and Year(date) will give you what you need.
Something like
SELECT EmpName
FROM Employees, Shifts
WHERE Employees.EmployeeID = Shifts.EmployeeID
AND
Month(Shifts.Day) = INPUT2.VALUE
AND
Year(Shifts.Day) = INPUT1.VALUE
should get you what you want!
EDIT: Aggregation: how this works will depend on how your database is set up. I think I understand you want to sum the hours worked and divide by the number of days?
If so, you will use Sum() and Count(). And you will Group By EmployeeID
SELECT Sum(Shifts)/Count(DaysWorked) AS SumDividedByCount
FROM EmployeesTBL INNER JOIN ShiftsTBL
ON EmployeesTBL.EmployeeID = ShiftsTBL.EmployeeID
WHERE
Year(ShiftsTBL.[Day])=[Enter Year]
AND
Month(ShiftsTBL.[Day])=[Enter Month]
GROUP BY EmployeeID
I used the WHERE clause because I think the results need to be filtered before they're grouped. If the results needed to be filtered after they were grouped, the HAVING clause would be used (and would go AFTER the GROUP BY)

understanding group by statements in rails

Given a invoices table like this:
invoice_date customer total
2012/01/01 A 780
2013/05/01 A 3800
2013/12/01 A 1500
2012/07/01 B 15
2013/03/01 B 21
Say that i want both:
the count of invoices of each customer of each year
the sum of the amounts of all the invoices of each customer of each year
the max amount among all the invoices of each customer of each year
That is, in SQL, very easily:
SELECT CUSTOMER, YEAR(invoice_date) as INVOICE_YEAR, MAX(total) AS MAX_TOTAL, SUM(total) AS SUM_AMOUNTS, count(*) AS INVOICES_NUM AS SUM_TOTAL FROM invoices GROUP BY YEAR(invoice_date), CUSTOMER;
(the function to extract the year of a date may be YEAR(date) or something else depending on the database server, on sqllite is strftime('%y', invoice_date))
Ok, i've tryed to translate this in rails/ActiveRecord:
Invoice.count(:group => 'customer')
This works, but how can i get both count and sum and max?
The idea i'm familiar with is that (in SQL) a group by generates the rows (well, to be correct, determines which rows should exist in the result table), and then you pass an arbitrary number of aggregation functions that are applyed on every disaggregate set of rows that are behind a single result row. E.G: group by customer means: one row for Customer A, one row for customer B; then I can pass how many aggregation function i want: count(*), max(total), max(date), min(total) just to list the most common.
Looking at the rails ActiveRecord API it seems that you're supposed to do just one function at a time, because the group is an argument of the count. And if i want a multiple aggregation functions, say max, sum etc?
Second attempt
irb> i = Invoice.select('customer, sum(total)').group('customer')
Invoice Load (0.3ms) SELECT customer, sum(total) AS TOTAL_GROUP FROM "invoices" GROUP BY customer
=> [#, #]
That is: it doesn't give back the field with the sum...
Well it does, it just doesn't get printed out.
Say you query is i = Invoice.select('customer, sum(total) as sum_total').group('customer')
So i is an array(technically it's not an array, but not important here) containing all the result. So i[0].sum_total will give you the sum of the first customer, but of course you should iterate it to get everything you want.