SQL daily sum report - sum

I have two tables, one is income which consists of ID, income_amount and date
the other is expenses which is ID, amount_spent and date.
I'm trying to display a table with three columns the daily total of income, the daily total of amount and the date for that day, it is possible for that day to have no income or amount but not necessarily both.
I was able to display the table in visual c# by gathering them in individual tables and deriving the results programmatically but is there a way to achieve that table with just a single sql query?

trunc_to_day here is an hypothetical function which truncates a date to its day (you didn't specify what RDMBS you are using):
select sum(incomes), sun(spent), day from (
(select income_amount incomes, 0 spent, trunc_to_day(datecol) day from income_table)
union all
(select 0 incomes, amount_spent spent, trunc_to_day(datecol) day from spent_table)
) group by day;
Finally, if you want to limit to some days, use a where statement on it.

Related

Optimize Average of Averages SQL Query

I have a table where each row is a vendor with a sale made on some date.
I'm trying to compute average daily sales per vendor for the year 2019, and get a single number. Which I think means I want to compute an average of averages.
This is the query I'm considering, but it takes a very long time on this large table. Is there a smarter way to compute this average without this much nesting? I have a feeling I'm scanning rows more times than I need to.
-- Average of all vendor's average daily sale counts
SELECT AVG(vendor_avgs.avg_daily_sales) avg_of_avgs
FROM (
-- Get average number of daily sales for each vendor
SELECT vendor_daily_totals.memberdeviceid, AVG(vendor_daily_totals.cnt)
avg_daily_sales
FROM (
-- Get total number of sales for each vendor
SELECT vendorid, COUNT(*) cnt
FROM vendor_sales
WHERE year = 2019
GROUP BY vendorid, month, day
) vendor_daily_totals
GROUP BY vendor_daily_totals.vendorid
) vendor_avgs;
I'm curious if there is in general a way to compute an average of averages more efficiently.
This is running in Impala, by the way.
I think you can just do the calculation in one shot:
SELECT AVG(t.avgs)
FROM (
SELECT vendorid,
COUNT(*) * 1.0 / COUNT(DISTINCT month, day) as avgs
FROM vendor_sales
WHERE year = 2019
GROUP BY vendorid
) t
This gets the total and divides by the number of days. However, COUNT(DISTINCT) might be even slower than nested GROUP BYs in Impala, so you need to test this.

SQL query solution for getting statistics from my tables

I have been trying to get statistics from my tables. In the following, I have tried to draw my table structure:
In the above, I have my Transaction table where each transaction is recorded for each user Profile(profile_id). As well as, I record transaction created date pub_date, transaction_type(type options are shown in the circle) and transaction amount. When transaction created I give Bonus to each transaction with appropriate Profile(profile_id).
So, I want to get statistics from above tables within the date range. More precisely:
Total transaction sum amount of each profile transaction within the date range with the transaction_types of WITHDRAW and WITHDRAW_MANUAL.
Total transaction sum amount of each profile transaction within the date range with the transaction_types of DEPOSIT and DEPOSIT_MANUAL.
Total Bonus sum amount of each profile transaction within the date range.
Visually, I want this result.
Here chosen date range means, I will give startDate and endDate period to the query
I could manage to solve 1. and 2.. But, I couldn't find way (for 3.) to SUM of each profiles' BONUS amount within the date range. My solution is as followings:
SELECT mtd.profile_id, sum(mtd.amount) AS summa_deposit,
(
SELECT sum(mtw.amount) AS summa_withdraw
FROM public.main_transaction AS mtw
WHERE mtw.profile_id=mtd.profile_id AND mtw.pub_date>='2017-01-01' AND mtw.pub_date<='2017-10-01' AND mtw.transaction_type IN ('WITHDRAW','WITHDRAW_MANUAL')
)
FROM public.main_transaction AS mtd
WHERE mtd.pub_date>='2017-01-01' AND mtd.pub_date<='2017-10-01' AND mtd.transaction_type IN ('DEPOSIT','DEPOSIT_MANUAL')
GROUP BY mtd.profile_id
ORDER BY mtd.profile_id;
Getting total amount of each profiles bonus is not a problem here. The problem is to get those amount within the date range. Because, I don't record date to my Bonus table. I only have my transaction_id and profile_id
P.S. my table is in the PostGreSQL.
Do you just need another join in a subquery?
(SELECT SUM(b.amount) AS summa_bonus
FROM public.bonus b JOIN
public.main_transaction mtw
ON b.transaction_id = mtw.id
WHERE mtw.profile_id = mtd.profile_id AND
mtw.pub_date >= '2017-01-01' AND
mtw.pub_date <= '2017-10-01' AND
mtw.transaction_type IN ('WITHDRAW', 'WITHDRAW_MANUAL')
)
I don't know if the filter on transaction_type is necessary.

BigQuery: Calculating averages in daily partitioned tables

I have a problem with getting averages out of several partitioned daily tables. We have partitioned tables for every day. I want to have an SQL query that calculates requests average for N days grouped by country.
So this is the schema:
date (string)
country (string)
req (integer)
What I have until now:
SELECT country, avg(req) as AvgReq
FROM TABLE_DATE_RANGE([thePartitionedTable_],
DATE_ADD(CURRENT_TIMESTAMP(), -2, 'DAY'), CURRENT_TIMESTAMP())
GROUP BY country
This works for 1 day of course, but the data is skewed when i try it for 2 or more days. What is the problem in my logic? How does the AVG() function work in this case? Do i need to group by date as well?
So i want the daily average of thePartitionedTable_today and daily average thePartitionedTable_yesterday then i want the average of their averages if that makes sense. So if thePartitionedTable_today has a daily average of 2 for Nigeria and thePartitionedTable_yesterday had a daily average of 3 for Nigeria, then the average for Nigeria of those two days should be 2.5. I really appriciate your time!
Using standard SQL:
with avg_byday AS (
SELECT
country,
AVG(req) AS req_avg
FROM
`thePartitionedTable_*`
GROUP BY
_TABLE_SUFFIX,
country)
SELECT
country,
AVG(req_avg)
FROM
avg_byday
GROUP BY
country
The subquery will also give you average requests per country for each day.

SQL Statement for MS Access Query to Calculate Quarterly Growth Rate

I have a table named "Historical_Stock_Prices" in a MS Access database. This table has the columns: Ticker, Date1, Open1, High, Low, Close1, Volume, Adj_Close. The rows consist of the data for each ticker for every business day.
I need to run a query from inside my VB.net program that will return a table in my program that displays the growth rates for each quarter of every year for each ticker symbol listed. So for this example I would need to find the growth rate for GOOG in the 4th quarter of 2012.
To calculate this manually I would need to take the Close Price on the last BUSINESS day of the 4th quarter (12/31/2012) divided by the Open Price of the first BUSINESS day of the 4th quarter (10/1/2012). Then I need to subtract by 1 and multiply by 100 in order to get a percentage.
The actual calculation would look like this: ((707.38/759.05)-1)*100 = -6.807%
The first and last days of each quarter may vary due to weekend days.
I cannot come up with the correct syntax for the SQL statement to create a table of Growth Rates from a table of raw Historical Prices. Can anyone help me with the SQL statment?
Here's how I would approach the problem:
I'd start by creating a saved query Access named [Stock_Price_with_qtr] that calculates the year and quarter for each row:
SELECT
Historical_Stock_Prices.*,
Year([Date1]) AS Yr,
Switch(Month([Date1])<4,1,Month([Date1])<7,2,Month([Date1])<10,3,True,4) AS Qtr
FROM Historical_Stock_Prices
Then I'd create another saved query in Access named [Qtr_Dates] that finds the first and last business days for each ticker and quarter:
SELECT
Stock_Price_with_qtr.Ticker,
Stock_Price_with_qtr.Yr,
Stock_Price_with_qtr.Qtr,
Min(Stock_Price_with_qtr.Date1) AS Qtr_Start,
Max(Stock_Price_with_qtr.Date1) AS Qtr_End
FROM Stock_Price_with_qtr
GROUP BY
Stock_Price_with_qtr.Ticker,
Stock_Price_with_qtr.Yr,
Stock_Price_with_qtr.Qtr
That would allow me to use the following query in VB.NET (or C#, or Access itself) to calculate the quarterly growth rates:
SELECT
Qtr_Dates.Ticker,
Qtr_Dates.Yr,
Qtr_Dates.Qtr,
(([Close_Prices]![Close1]/[Open_Prices]![Open1])-1)*100 AS Qtr_Growth
FROM
(
Historical_Stock_Prices AS Open_Prices
INNER JOIN Qtr_Dates
ON (Open_Prices.Ticker = Qtr_Dates.Ticker)
AND (Open_Prices.Date1 = Qtr_Dates.Qtr_Start)
)
INNER JOIN
Historical_Stock_Prices AS Close_Prices
ON (Qtr_Dates.Ticker = Close_Prices.Ticker)
AND (Qtr_Dates.Qtr_End = Close_Prices.Date1)

How do I calculate a profit for each month in MS Access?

I'm quite new to access and I am currently in the process of making a database for my company.
I have a 'Jobs' table with these fields in:
Job No.
Year Initiated
Month Initiated
Company ID
Job Description
Amount Quoted
Amount to Invoice
Invoice Number
Completed By
Cost
Profit
What I want to know Is what is the best way/ how do I calculate either in a form or query the overall profit for each month?
Please help, the database is really coming along, apart from this is well entruely stuck on.
You want to find all rows matching a specific year / month, and add together all the profit entries for that month to get a total?
If so, try this :
select sum(profit) from Jobs where year = 2013 and month = 02
Or, if you want to retrieve this information for all months in one go, try this :
select year, month, sum(profit) from Jobs group by year, month