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.
Related
I made really simple example table with columns date and credit, so we can sum all credit to get account saldo of the account. I can sum all credit values to get saldo, but that is not what I want. I want to calculate average saldo, so in order to do that I need to use RangeDate table with date of every day and query with this logic:
SELECT DRA.date, SUM(ACB.credit)
FROM AccountBalance ACB
JOIN DateRange DRA ON ACB.date <= DRA.date
GROUP BY DRA.date
http://sqlfiddle.com/#!18/88afa/10
the problem is when using this program on a larger range of dates, like whole year for example.
Instruction is telling SQL Engine to sum up all rows of credit before the current date including credit of the current row date (where the cursor is in that moment (JOIN... ACB.date <= DRA.date)), in order to get accounts credit for that day.
This is inefficient and slow for big tables because that sum already exists in the row 1 level before, and I would like to tell SQL Engine to take that sum and only add the one row of credit that it is in.
Somone told me that I should use LAG function, but i need an example first.
I think you simply need an analyitc function -
SELECT DRA.date,
SUM(ACB.saldo) OVER (ORDER BY DRA.date)
FROM DateRange DRA
LEFT JOIN AccountBalance ACB ON ACB.date = DRA.date;
Demo.
I'm creating a cube whose stock values should only conclude the last day each month's balance and value.
Hence, I've created the following Query in SSMS:
Create table #theStockTable(
Stock int,
StockValue INT,
DateKey int
)
INSERT INTO #theStockTable
VALUES(3,5, 20170211),
(3,5,20170228),
(1,4,20170331),
(1,4,20170330)
SELECT CAST(CONVERT(varchar, DateKey, 112) AS numeric(8, 0)) AS DateKey, SUM(Stock) AS [CL Stock], SUM(StockValue) AS [CL Stock Value]
FROM #theStockTable
WHERE CONVERT(date, CONVERT(varchar(10), DateKey)) = eomonth(CONVERT(date, CONVERT(varchar(10), DateKey)))
GROUP BY DateKey
In SSMS this returns the correct values:
DateKey CL Stock CL Stock Value
20170228 3 5
20170331 1 4
However, when I create an OLAP cube using SSAS, and use the Query above as the Named Query for my fact table #theStockTable and the same Query as my only partition of the same fact table and deploy and execute the cube, I have a situation where I get different values on each day of every month, but I only want to have the values for each month's last day.
I have used New Project.. -> Import from Server (multidimensional model or data mining model) in SSAS. It is important that the users must be able to browse the cube as they presently do.
The cube whose meta data I have copied contains every day's values on the stock table. May there be some metadata change I need to make in addition to the Query modification I have done in Edit named Query.. in Data Source View and replacing the old Query in the partition with my new Query?
Hopefully someone can shed some light into this.
EDIT
To clarify my request, some users of the cube has explained that it is rather slow to browse in for instance Excel, mainly because my Stock measure is much bigger than it is required to be. As it is now, it returns every StockValue and Stock of each product and each day. I want to only include the total balance of StockValue and Stock of the last day of the month. All other stock values are redundant.
For instance, browsing my DimDate dimension table with the measurements Stock and StockValue should have this return set:
DateKey Stock StockValue
20170131 0 0
rather than the whole return set which is returned now:
DateKey Stock StockValue
20170101 3 5
20170102 4 6
20170103 1 1
20170131 0 0
I think you already had a date dimension in your cube, if yes, then follow these steps:
Add an additional attribute [IsLastDay] with value 0/1 in the date dimension to indicate if the current date record is the last day of that month or not.
2.Add a calculate measure [CalStock] with this formular:
([Measures].[StockValue],[Date].[IsLastDay].&[1])
3.Fire this query to return the expected result:
select {[CalStock]} on 0,
non empty{[Date].[Date].[Date]} on 1
from [YourCube]
I'm trying to create a measure that displays buckets of AR values from our accounting system. The billing table is structured in a way where a row is created for each financial transaction related to a bill: one record shows the billed amount and a separate record, related by a bill key, shows one or more payments to the bill. I am able to create multiple measures that sum the bill amounts and break these out by Current, 30, 60, 90 and 120 day buckets (admittedly, this is new to me so even this measure might not be right):
AR Current =
VAR EndDate = TODAY()
VAR StartDate = EndDate - 29
RETURN
CALCULATE(
[Billings],
DATESBETWEEN(
'Date'[Date], StartDate, EndDate
)
)
The issue I have is trying to sum up the collections. The collections are not aged, but the total amounts collected for a specific bill need to be subtracted from the total billings in each aging bucket. Regardless of the date range, I need to get a list of all Bill Keys for each bucket, use those keys to sum the values for the Collections column, and subtract from the total within a bucket.
The only equivalent I can think of is a SQL query:
--This example gets the billed amount for anything less than 30 days old)
SELECT BILLKEY, SUM(BILLAMOUNT) BILLAMOUNT
FROM tblBilling
WHERE BILLDATE BETWEEN GETDATE()-30 AND GETDATE()
GROUP BY BILLKEY
-- This gets the corresponding collections:
SELECT BILLKEY, SUM(COLECTION) COLLECTION
FROM tblBilling
WHERE BILLKEY IN (
SELECT BILLKEY FROM tblBillings WHERE BILLDATE BETWEEN GETDATE()-30 AND GETDATE()
)
GROUP BY BILLKEY
Any help would be greatly appreciated.
Thanks,
Eric
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)
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.