How to assign equal revenue weight to every location of a company in a table? Google Big Query - sql

I am working on a problem where I have the following table:
+----------+ | +------+ | +------------+
company_id | country | total revenue
1 Russia 1200
2 Croatia 1200
2 Italy 1200
3 USA 1200
3 UK 1200
3 Italy 1200
There are 3 companies in this table, but company '2' and company '3' have offices in 2 and 3 countries respectively. All companies pay 1200 per month, and because company 2 has 2 offices it shows as if they paid 1200 per month 2 times, and because company 3 has 3 offices it shows as if it paid 1200 per month 3 times. Instead, I would like revenue to be equally distributed based on how many times company_id appears in the table. company_id will only appear more than once for every additional country in which a company is based.
Assuming each company always pays 1,200 per month, my desired output is:
+----------+ | +------+ | +------------+
company_id | country | total revenue
1 Russia 1200
2 Croatia 600
2 Italy 600
3 USA 400
3 UK 400
3 Italy 400
Being new to SQL, I was thinking this can maybe be done through CASE WHEN statement, but I only learned to use CASE WHEN when I want to output a string depending on a condition. Here, I am trying to assign equal revenue weight to each company's country, depending on in how many countries a company is based in.
Thank you in advance for you help!

Below is for BigQuery Standard SQL
#standardSQL
SELECT company_id, country,
total_revenue / (COUNT(1) OVER(PARTITION BY company_id)) AS total_revenue
FROM `project.dataset.table`
If to apply to sample data from your question - output is
Row company_id country total_revenue
1 1 Russia 1200.0
2 2 Croatia 600.0
3 2 Italy 600.0
4 3 USA 400.0
5 3 UK 400.0
6 3 Italy 400.0

Related

Quicksight Calculated field: sum of average?

The dataset I have is currently like so:
country
itemid
device
num_purchases
total_views_per_country_and_day
day
USA
ABC
iPhone11
2
900
2022-06-15
USA
ABC
iPhoneX
5
900
2022-06-15
USA
DEF
iPhoneX
8
900
2022-06-15
UK
ABC
iPhone11
10
350
2022-06-15
UK
DEF
iPhone11
20
350
2022-06-15
total_views_per_country_and_day is already pre-calculated to be the sum grouped by country and day. That is why for each country-day pair, the number is the same.
I have a Quicksight analysis with a filter for day.
The first thing I want is to have a table on my dashboard that shows the number of total views for each country.
However, if I were to do it with the dataset just like that, the table would sum everything:
country
total_views
USA
900+900+900=2700
UK
350+350=700
So what I did was, create a calculated field which is the average of total_views. Which worked---but only if my day filter on dashboard was for ONE day.
When filtered for day = 2022-06-15: correct
country
avg(total_views)
USA
2700/3=900
UK
700/2=350
But let's say we have data from 2022-06-16 as well, the averaging method doesn't work, because it will average based on the entire dataset. So, example dataset with two days:
country
itemid
device
num_purchases
total_views_per_country_and_day
day
USA
ABC
iPhone11
2
900
2022-06-15
USA
ABC
iPhoneX
5
900
2022-06-15
USA
DEF
iPhoneX
8
900
2022-06-15
UK
ABC
iPhone11
10
350
2022-06-15
UK
DEF
iPhone11
20
350
2022-06-15
USA
ABC
iPhone11
2
1000
2022-06-16
USA
ABC
iPhoneX
5
1000
2022-06-16
UK
ABC
iPhone11
10
500
2022-06-16
UK
DEF
iPhone11
20
500
2022-06-16
Desired Table Visualization:
country
total_views
USA
900 + 1000 = 1900
UK
350 + 500 = 850
USA calculation: (900 * 3)/3 + (1000 * 2) /2 = 900 + 1000
UK calculation: (350 * 2) /2 + (500 * 2) /2 = 350 + 500
Basically---a sum of averages.
However, instead it is calculated like:
country
avg(total_views)
USA
[(900 * 3) + (1000*2)] / 5 = 940
UK
[(350 * 2) + (500 * 2)] / 4 = 425
I want to be able to use this calculation later on as well to calculate num_purchases / total_views. So ideally I would want it to be a calculated field. Is there a formula that can do this?
I also tried, instead of calculated field, just aggregating total_views by average instead of sum in the analysis -- exact same issue, but I could actually keep a running total if I include day in the table visualization. E.G.
country
day
running total of avg(total_views)
USA
2022-06-15
900
USA
2022-06-16
900+1000=1900
UK
2022-06-15
350
UK
2022-06-16
350+500=850
So you can see that the total (2nd and 4th row) is my desired value. However this is not exactly what I want.. I don't want to have to add the day into the table to get it right.
I've tried avgOver with day as a partition, that also requires you to have day in the table visualization.
sum({total_views_per_country_and_day}) / distinct_count( {day})
Basically your average is calculated as sum of metric divided by number of unique days. The above should help.

Function to get rolling average with lowest 2 values eliminated?

This is my sample data with the current_Rating column my desired output.
Date Name Subject Importance Location Time Rating Current_rating
12/08/2020 David Work 1 London - - 4
1/08/2020 David Work 3 London 23.50 4 3.66
2/10/2019 David Emails 3 New York 18.20 3 4.33
2/08/2019 David Emails 3 Paris 18.58 4 4
11/07/2019 David Work 1 London - 3 4
1/06/2019 David Work 3 London 23.50 4 4
2/04/2019 David Emails 3 New York 18.20 3 5
2/03/2019 David Emails 3 Paris 18.58 5 -
12/08/2020 George Updates 2 New York - - 2
1/08/2019 George New Appointments5 London 55.10 2 -
I need to use a function to get values in the current_Rating column.The current_Rating gets the previous 5 results from the rating column for each name, then eliminates the lowest 2 results, then gets the average for the remaining 3. Also some names may not have 5 results, so I will just need to get the average of the results if 3 or below, if 4 results I will need to eliminate the lowest value and average the remaining 3. Also to get the right 5 previous results it will need to be sorted by date. Is this possible? Thanks for your time in advance.
What a pain! I think the simplest method might be to use arrays and then unnest() and aggregate:
select t.*, r.current_rating
from (select t.*,
array_agg(rating) over (partition by name order by date rows between 4 preceding and current row) as rating_5
from t
) t cross join lateral
(select avg(r) as current_rating
from (select u.*
from unnest(t.rating_5) with ordinality u(r, n)
where r is not null
order by r desc desc
limit 3
) r
) r

Query with sum functions

for a little project(hobby purpose) i am building a C# application with a SQL database behind it.
However I am trying to build a query with a sum function which calculates values from a different table.
Here are the relevant tables and sample data
Hotel table
Id, Name Adress Zipcode Phone
1 Ankunding Group 90 Shelley Terrace 649-6326 86-(672)239-5855
2 Gerlach-Gutmann 50776 Bartillon Road 27109 CEDEX 33-(412)226-8055
3 Breitenberg-Smith 3289 Talisman Avenue 59762 86-(141)636-8780
4 Smitham-Marks 5 Veith Plaza 216282 7-(400)484-7233
5 Beatty LLC 3 Center Pass 940028 212-(310)974-4364
Reservation table
id, customerid, Startdate Enddate Amount of persons
1 163 2016-06-19 2017-04-30 4
2 172 2016-12-02 2016-08-18 5
3 162 2017-01-20 2017-04-08 3
4 66 2017-04-06 2017-01-07 2
5 104 2017-05-07 2016-09-10 2
RoomReservation table
Roomid, reservationid
3 53
3 198
4 178
5 172
5 218
Room table
id, hotelid, Roomnumber, price
1 1 1.01 268.83
2 1 1.02 201.28
3 1 1.03 126.64
4 1 1.04 122.56
5 1 1.05 217.41
Now I am trying to make a query to which gives me an overview off income per hotel. So for each hotel I want to get the reservations, and do amount of persons * the price of the room for each room in the hotel.
I've tried different things without success, I read somewhere that I needed to use a subquery but I have no idea how.
I want it to look like;
Hotelname1; income
Hotelname2; income
Hotelname3; income
Hotelname4; income
Hotelname4; income
Why can't you just do this:
SELECT
Hotel.Name,
SUM(Room.Price*Reservation.Amountofpersons)
FROM
Hotel
JOIN Room
ON Hotel.HotelId=Room.HotelId
JOIN RoomReservation
ON Room.RoomId=RoomReservation.RoomId
JOIN Reservation
ON RoomReservation.ReservationId=Reservation.ReservationId
GROUP BY
Hotel.Name
You can try it whit this query:
select hotel.name,sum(reservation.amount*room.price)
from hotel_table as hotel
inner join room_table as room on (hotel.hotelid=room.hotelid)
inner join roomreservation_table as room_reservation on (room.roomid=room_reservation.roomId)
inner join reservation_table as reservation on (room.reservationId=reservation.reservationid)
group by hotel.hotelid

Create all combinations of summations given criteria in Access VBA

I have a subset summation problem I cannot find the answer to. I am trying to write something in VBA for access that will take all combinations of summations within a certain criteria and place them in a table so I can match a different table to it. Right now I am more concerned with creating the table of combinations. First time I have asked a question sorry if I mess something up.
Example:
Access Table: ImpTable
Fields: ID, Year-Month, Name, Country, Quantity
I need to make every combination of summations where the country and Year-Month are the same. Yet keep track of what was included in the formula. If the new table was created and kept track of which ID's were included in the combination I can reference the original table for the name.
Expected Ending Table Results:
NewID, Year-Month, Country, SumQuantity, ComboName (ID's from original table)
Any help is appreciated.
Raw Data:
ID Year-Month Name Country Quantity
1 2016-06 Person1 US 10
2 2016-06 Person2 US 12
3 2016-10 Person3 US 4
4 2016-06 Person4 UK 5
5 2016-06 Person5 UK 6
6 2016-06 Person6 US 3
Desired Results:
NewID Year-Month Country SumQuantity ComboName
1 2016-06 US 22 1,2
2 2016-06 US 13 1,6
3 2016-06 US 25 1,2,6
4 2016-06 US 15 2,6
5 2016-06 UK 11 4,5
6 2016-10 US 4 3

Joining tables with different column name but same value in sqlite

I'm using SQLite to work with my database
I have two different tables, with key columns that have different names but the same value.
As such:
shoes
Identification | Name | Shoe size
1 Bob 10
2 John 12
payment
PaymentID | Price | Year
1 20 2013
2 38 2015
I need
Identification(or PaymentID, no matter) | Name | Shoe size | Price | Year
1 Bob 10 20 2013
2 John 12 38 2015
I've been searching, and trying to understand the tutorials to no avail. I guess im just too stupid
select s.identification, s.name, s.`shoe size`, p.price, p.year
from shoes s
join payment p on p.paymentid = s.identification