Transpose groups/subgroups in sql oracle - sql

I have date column which i have to divide in 6 quarters and calculate count,ratio- A/Count, Avg(colC) by State. Date column i have converted to YYYY Q format. I was wondering if i can get results shown below. i am using oracle 11g. I am just trying to write a sql which can give me results in above format. I am able to Group results in quarter but unable to further subgroup it to show count,Ratio and Avg under each quarter. –
I have 2 tables that i need to use to get data below.
Table 1 Table 2
Customer_id St_Nme St_Cd Customer_id No_of_sales Time_spent Date
1 Alabama AL 1 4 4.5 01122012
2 California CA 2 7.5 9.33 03062012
Desired Output
Count-Count of sales
Ratio-Time_spent/Count of sales
Avg - Average of time spent
Q42012 Q32012 Q22012 Q12012 Q42011 Q32012
count Ratio Avg count Ratio Avg count Ratio Avg
State
Alabama 3 4.5 1.2 8 7.4 3.2 65 21.1 34.4
A.. 4 7.5 3.2 5 9.4 5.2 61 25.1 39.4
A.. 9 6.5 5.2 4 3.4 3.7 54 41.1 44.4
Boston
Cali..
Den..

Related

Google BigQuery select max for each day

I have a problem with my BigQuery select, I need to get the max value for the column (students) for each day.
SELECT EXTRACT(DATE FROM timestamp) as date, ARRAY_LENGTH(student_ids) as students from analytics.daily_active_students_count order by timestamp desc
Row
Date
Students
1
2022-05-16
72
2
2022-05-16
33
3
2022-05-16
12
4
2022-05-15
10
5
2022-05-15
84
6
2022-05-15
8
7
2022-05-14
92
8
2022-05-14
105
9
2022-05-14
12
Query should remove duplicated rows for days and take only rows with max number of students.
I want my output looks like this:
Row
Date
Students
1
2022-05-16
72
2
2022-05-15
84
3
2022-05-14
105
Problem was that my backend used different timezone. I solved this issue with casting timestamp:
DATE(DATETIME(TIMESTAMP, "Europe/Zagreb")) as date

Showing Two Fields With Different Timeline in the Same Date Structure

In the project I am currently working on in my company, I would like to show sales related KPIs together with Customer Score metric on SQL / Tableau / BigQuery
The primary key is order id in both tables. However, order date and the date we measure Customer Score may be different. For example the the sales information for an order that is released in Feb 2020 will be aggregated in Feb 2020, however if the customer survey is made in March 2020, the Customer Score metric must be aggregated in March 2020. And what I would like to achieve in the relational database is as follows:
Sales:
Order ID
Order Date(m/d/yyyy)
Sales ($)
1000
1/1/2021
1000
1001
2/1/2021
2000
1002
3/1/2021
1500
1003
4/1/2021
1700
1004
5/1/2021
1800
1005
6/1/2021
900
1006
7/1/2021
1600
1007
8/1/2021
1900
Customer Score Table:
Order ID
Customer Survey Date(m/d/yyyy)
Customer Score
1000
3/1/2021
8
1001
3/1/2021
7
1002
4/1/2021
3
1003
6/1/2021
6
1004
6/1/2021
5
1005
7/1/2021
3
1006
9/1/2021
1
1007
8/1/2021
7
Expected Output:
KPI
Jan-21
Feb-21
Mar-21
Apr-21
May-21
June-21
July-21
Aug-21
Sep-21
Sales($)
1000
2000
1500
1700
1800
900
1600
1900
AVG Customer Score
7.5
3
5.5
3
7
1
I couldn't find a way to do this, because order date and survey date may/may not be the same.
For sample data and expected output, click here.
I think what you want to do is aggregate your results to the month (KPI) first before joining, as opposed to joining on the ORDER_ID
For example:
with order_month as (
select date_trunc(order_date, MONTH) as KPI, sum(sales) as sales
from `testing.sales`
group by 1
),
customer_score_month as (
select date_trunc(customer_survey_date, MONTH) as KPI, avg(customer_score) as avg_customer_score
from `testing.customer_score`
group by 1
)
select coalesce(order_month.KPI,customer_score_month.KPI) as KPI, sales, avg_customer_score
from order_month
full outer join customer_score_month
on order_month.KPI = customer_score_month.KPI
order by 1 asc
Here, we aggregate the total sales for each month based on the order date, then we aggregate the average customer score for each month based on the date the score was submitted. Now we can join these two on the month value.
This results in a table like this:
KPI
sales
avg_customer_score
2021-01-01
1000
null
2021-02-01
2000
null
2021-03-01
1500
7.5
2021-04-01
1700
3.0
2021-05-01
1800
null
2021-06-01
900
5.5
2021-07-01
1600
3.0
2021-08-01
1900
7.0
2021-09-01
null
1.0
You can pivot the results of this table in Tableau, or leverage a case statement to pull out each month into its own column - I can elaborate more if that will be helpful

Subtract grouped aggregate column by another in 3 table join query

I'm pretty new to joinings and advanced querying, what I want to do is to join three tables to make an summary of how many hours an employee has spent on courses (course data is omitted from examples).
!-SQL query is below the example table-!
The query must show:
A unique set of employee name.
Their individual allocated hours.
A sum of their hours spent
And return a final new column showing the allowance left.
"employees" table
id
employee_id
1
"Annachiara Darius"
2
"Samar Rajani"
3
"Taonga Eric"
4
"Tycho Sigdag"
5
"Naevius Matvei"
6
"Theophania Eglantine"
7
"Boro Stanislav"
"accounting" table where hours are recorded
id
employee_id
hours_done
1
1
2.50
2
1
2.80
3
2
5.60
4
2
3.30
5
4
4.50
6
5
8.90
7
6
7.60
8
3
6.50
9
7
1.00
10
5
10.30
11
7
11.50
12
5
5.60
13
7
100.00
14
2
30.00
"allocation" table
id
employee_id
hours_allocated
1
1
12
2
2
16
3
3
20
4
4
15
5
5
10
6
6
7
7
7
8
SELECT ACCOUNTING.EMPLOYEE_ID AS EMPLOYEE_ID,
EMPLOYEE.EMPLOYEE_NAME AS EMPLOYEE_NAME,
ALLOCATED.HOURS_ALLOCATED,
SUM(ACCOUNTING.HOURS_DONE) AS HOURS_SPENT,
SUM(ALLOCATED.HOURS_ALLOCATED - ACCOUNTING.HOURS_DONE) AS ALLOWANCE
FROM PUBLIC.ACCOUNTING ACCOUNTING
INNER JOIN
(SELECT EMPLOYEE_NAME,
EMPLOYEE_ID
FROM PUBLIC.EMPLOYEES GROUP
BY EMPLOYEE_ID) EMPLOYEE ON EMPLOYEE.EMPLOYEE_ID = ACCOUNTING.EMPLOYEE_ID
INNER JOIN
(SELECT HOURS_ALLOCATED,
EMPLOYEE_ID
FROM PUBLIC.ALLOCATION GROUP
BY EMPLOYEE_ID,
HOURS_ALLOCATED) ALLOCATED ON ALLOCATED.EMPLOYEE_ID = ACCOUNTING.EMPLOYEE_ID GROUP
BY ACCOUNTING.EMPLOYEE_ID,
EMPLOYEE_NAME,
ALLOCATED.HOURS_ALLOCATED
ORDER
BY EMPLOYEE_NAME ASC
Result from the query above
employee_id
employee_name
hours_allocated
hours_spent
allowance
1
"Annachiara Darius"
12
5.3
18.7
7
"Boro Stanislav"
8
112.5
-88.5
5
"Naevius Matvei"
10
24.8
5.2
2
"Samar Rajani"
16
38.9
9.1
3
"Taonga Eric"
20
6.5
13.5
6
"Theophania Eglantine"
7
7.6
-0.6
4
"Tycho Sigdag"
15
4.5
10.5
As you can see I've managed to get every column displaying the information I wanted correctly.
The problem:
Allowence column is only correct if the employee has only made one entry in the accounting table.
If employee has more than one entry in accounting the calculation is off/wrong.
The line I use to get the allowance is
SUM(ALLOCATED.HOURS_ALLOCATED - ACCOUNTING.HOURS_DONE) AS ALLOWANCE
I've been trying different stuff but can't seem to manage this part of the query.
How can I incorporate this into the group logic?
The answer was posted in a comment.
ALLOCATED.HOURS_ALLOCATED - SUM(ACCOUNTING.HOURS_DONE) is correct
but not
`SUM(ALLOCATED.HOURS_ALLOCATED - ACCOUNTING.HOURS_DONE)` AS ALLOWANCE

I want to do some aggregations with the help of Group By function in pandas

My dataset consists of a date column in 'datetime64[ns]' dtype; it also has a price and a no. of sales column.
I want to calculate the monthly VWAP (Volume Weighted Average Price ) of the stock.
( VWAP = sum(price*no.of sales)/sum(no. of sales) )
What I applied is:-
created a new dataframe column of month and year using pandas functions.
Now, I want monthly VWAP from this dataset which I modified, also, it should be distinct by year.
For eg. - March,2016 and March,2017 should have their seperate VWAP monthly values.
Start from defining a function to count vwap for the current
month (group of rows):
def vwap(grp):
return (grp.price * grp.salesNo).sum() / grp.salesNo.sum()
Then apply it to monthly groups:
df.groupby(df.dat.dt.to_period('M')).apply(vwap)
Using the following test DataFrame:
dat price salesNo
0 2018-05-14 120.5 10
1 2018-05-16 80.0 22
2 2018-05-20 30.2 12
3 2018-08-10 75.1 41
4 2018-08-20 92.3 18
5 2019-05-10 10.0 33
6 2019-05-20 20.0 41
(containing data from the same months in different years), I got:
dat
2018-05 75.622727
2018-08 80.347458
2019-05 15.540541
Freq: M, dtype: float64
As you can see, the result contains separate entries for May in both
years from the source data.

Subtract nonconsecutive values in same row in t-SQL

I have a data table that has annual data points and quarterly data points. I want to subtract the quarterly data points from the corresponding prior annual entry, e.g. Annual 2014 - Q3 2014, using t-SQL. I have an id variable for each entry, plus a reconcile id variable that shows which quarterly entry corresponds to which annual entry. See below:
CurrentDate PreviousDate Value Entry Id Reconcile Id Annual/Quarterly
9/30/2012 9/30/2011 112 2 3 Annual
9/30/2013 9/30/2012 123 1 2 Annual
9/30/2014 9/30/2013 123.5 9 1 Annual
12/31/2013 9/30/2014 124 4 1 Quarterly
3/31/2014 12/31/2013 124.5 5 1 Quarterly
6/30/2014 3/31/2014 125 6 1 Quarterly
9/30/2014 6/30/2014 125.5 7 1 Quarterly
12/31/2014 9/30/2014 126 10 9 Quarterly
3/31/2015 12/31/2014 126.5 11 9 Quarterly
6/30/2015 3/31/2015 127 12 9 Quarterly
For example, Reconcile ID 9 for the quarterly entries corresponds to Entry ID 9, which is an annual entry.
I have code to just subtract the prior entry from the current entry, but I cannot figure out how to subtract quarterly entries from annual entries where the Entry ID and Reconcile ID are the same.
Here is the code I am using, which is resulting in the right calculation, but increasing the number of results by many rows. I have also tried this as an inner join. I only want the original 10 rows, plus a new difference column:
SELECT DISTINCT T1.[EntryID]
, [T1].[RECONCILEID]
, [T1].[CurrentDate]
, [T1].[Annual_Quarterly]
, [T1].[Value]
, [T1].[Value]-T2.[Value] AS Difference
FROM Table T1
LEFT JOIN Table T2 ON T2.EntryID = T1.RECONCILEID;
Your code should be fine, here's the results I'm getting:
EntryId Annual_Quarterly CurrentDate ReconcileId Value recVal diff
2 Annual 9/30/2012 3 112
1 Annual 9/30/2013 2 123 112 11
9 Annual 9/30/2014 1 123.5 123 0.5
4 Quarterly 12/31/2013 1 124 123 1
5 Quarterly 3/31/2014 1 124.5 123 1.5
6 Quarterly 6/30/2014 1 125 123 2
7 Quarterly 9/30/2014 1 125.5 123 2.5
10 Quarterly 12/31/2014 9 126 123.5 2.5
11 Quarterly 3/31/2015 9 126.5 123.5 3
12 Quarterly 6/30/2015 9 127 123.5 3.5
with your data and this SQL:
SELECT
tr.EntryId,
tr.Annual_Quarterly,
tr.CurrentDate,
tr.ReconcileId,
tr.Value,
te.Value AS recVal,
tr.[VALUE]-te.[VALUE] AS diff
FROM
t AS tr LEFT JOIN
t AS te ON
tr.ReconcileId = te.EntryId
ORDER BY
tr.Annual_Quarterly,
tr.CurrentDate;
Your question is a bit vague as far as how you're wanting to subtract these values, but this should give you some idea.
Select T1.*, T1.Value - Coalesce(T2.Value, 0) As Difference
From Table T1
Left Join Table T2 On T2.[Entry Id] = T1.[Reconcile Id]