SQL: Calculate the number of Days in a Month with no stock - sql

I am trying to create a query than can calculate the number of days, in a given month, that a particular stock item was unavailable (ie: No. = 0).
Currently, I have developed a query that can calculate the number of days it has been from today's date where stock has been unavailable but what I am trying to actually calculate is, during a month, how many days was stock quantity = 0. ie: Month of Jan - on Jan 5, Jan 7 and Jan 20 there was no stock for Item A - this means that the number of days out of stock was = 3.
Extra Details:
Currently, I am basing my query in determining stock levels of the last transaction (ie: if, at the last transaction, the QTY of Stock = 0) then calculate the number of days between the transaction date and today.
Select [StockItems].StockCode,
Case When SUM([StockItems].Qty_On_Hand)=0 Then (Datediff(day, GETDATE(),MAX([Transactions].TransactionDate))) ELSE 0 END AS 'Days Out of Stock',
From dbo.[Transactions]
INNER JOIN [StockItems]
ON [Transactions].[AccountLink] = [StockItems].[StockLink]
Where [StockItems].StockCode LIKE '%XXX%'
AND [Transactions].TransactionDate>31/10/14
Group By [StockItems].StockCode
My Thoughts
There are different sorts of transactions - one of which is a good received transaction. Perhaps it is possible to calculate the days where Stock Qty was zero and a transaction occurred then count that date until goods were received.
Thoughts?
Thank You.

SELECT COUNT([StockItems].Qty_On_Hand
From dbo.[Transactions]
INNER JOIN [StockItems] ON [Transactions].[AccountLink] = [StockItems].[StockLink]
WHERE [StockItems].Qty_On_Hand)=0

Related

SQLite - Determine average sales made for each day of week

I am trying to produce a query in SQLite where I can determine the average sales made each weekday in the year.
As an example, I'd say like to say
"The average sales for Monday are $400.50 in 2017"
I have a sales table - each row represents a sale you made. You can have multiple sales for the same day. Columns that would be of interest here:
Id, SalesTotal, DayCreated, MonthCreated, YearCreated, CreationDate, PeriodOfTheDay
Day/Month/Year are integers that represent the day/month/year of the week. DateCreated is a unix timestamp that represents the date/time it was created too (and is obviously equal to day/month/year).
PeriodOfTheDay is 0, or 1 (day, or night). You can have multiple records for a given day (typically you can have at most 2 but some people like to add all of their sales in individually, so you could have 5 or more for a day).
Where I am stuck
Because you can have two records on the same day (i.e. a day sales, and a night sales, or multiple of each) I can't just group by day of the week (i.e. group all records by Saturday).
This is because the number of sales you made does not equal the number of days you worked (i.e. I could have worked 10 saturdays, but had 30 sales, so grouping by 'saturday' would produce 30 sales since 30 records exist for saturday (some just happen to share the same day)
Furthermore, if I group by daycreated,monthcreated,yearcreated it works in the sense it produces x rows (where x is the number of days you worked) however that now means I need to return this resultset to the back end and do a row count. I'd rather do this in the query so I can take the sales and divide it by the number of days you worked.
Would anyone be able to assist?
Thanks!
UPDATE
I think I got it - I would love someone to tell me if I'm right:
SELECT COUNT(DISTINCT CAST(( julianday((datetime(CreationDate / 1000, 'unixepoch', 'localtime'))) ) / 7 AS INT))
FROM Sales
WHERE strftime('%w', datetime(CreationDate / 1000, 'unixepoch'), 'localtime') = '6'
AND YearCreated = 2017
This would produce the number for saturday, and then I'd just put this in as an inner query, dividing the sale total by this number of days.
Buddy,
You can group your query by getting the day of week and week number of day created or creation date.
In MSSQL
DATEPART(WEEK,'2017-08-14') // Will give you week 33
DATEPART(WEEKDAY,'2017-08-14') // Will give you day 2
In MYSQL
WEEK('2017-08-14') // Will give you week 33
DAYOFWEEK('2017-08-14') // Will give you day 2
See this figures..
Day of Week
1-Sunday, 2- Monday, 3-Tuesday, 4-Wednesday, 5-Thursday, 6-Saturday
Week Number
1 - 53 Weeks in a year
This will be the key so that you will have a separate Saturday's in every month.
Hope this can help in building your query.

T-Sql business rule calculation

I have a complicated problem that needs to be solved in t-sql. Possibly without a cursor or a loop.
Given the following table with customer’s payment setup.
ID Frequency Amount Start Date End Date
1 Monthly 100 01-01-2016 N/A(ongoing)
The customer wants to know how much he\she will have to pay for the month of November.
If they were to close the account on 15 nov 2016.
For example:
Assume the customer wants to close their account on 15-nov-2016 and wants to know the $amount they will be paying from 1st of November to 15 of November.
Calculation
The frequency cycle for the customer payment is Monthly.
Taking the frequency into account we know that:
Customer start date of November will be 1st of November
The end date will be 30 November
Calculation formula
(DayUpToCloseDate/DaysInNov) * Amount = amount customer is asking.
DaysUpToCloseDate = 15 (diff 1st of nov and 15th of nov)
DaysInNov = 30
Amount = 100
(15/30)*100 = 50
So we can tell the customer he/she will be paying 50$ in November if they were to close the account on 15th of November.
First we need to declare the 2 variables, the date in question and the monthly amount due.
DECLARE #date datetime = '2017-11-15'
DECLARE #amountDue int = 100
Then to get the month to date amount due we can use:
SELECT CAST(DATEPART(DAY,#date) AS FLOAT)/DATEPART(DAY,DATEADD(MONTH,DATEDIFF(MONTH,0,#date)+1,0)-1) * #amountDue AS [MonthToDateAmountDue]
Here is how we got there.
SELECT
--This gets the first day of the next month and subtracts 1 day, getting the last day of the month the date falls in.
DATEADD(MONTH,DATEDIFF(MONTH,0,#date)+1,0)-1 AS [LastDayOfMonth]
--We now extract the day date part of the last day of the month to get the total days in the month.
,DATEPART(DAY,DATEADD(MONTH,DATEDIFF(MONTH,0,#date)+1,0)-1) AS [DaysInMonth]
--Finally, we get the day date part from our #date and divide by the total days of the month to get the percentage of the month we have completed.
--Since int does not do decimals, we use a float.
,CAST(DATEPART(DAY,#date) AS FLOAT)/DATEPART(DAY,DATEADD(MONTH,DATEDIFF(MONTH,0,#date)+1,0)-1) AS [PercentageOfMonthCompleted]
--And mulitply it by the amount due.
,CAST(DATEPART(DAY,#date) AS FLOAT)/DATEPART(DAY,DATEADD(MONTH,DATEDIFF(MONTH,0,#date)+1,0)-1) * #amountDue AS [MonthToDateAmountDue]
Edit: So, I just learned about the EOMONTH function. This can be shortened to
SELECT CAST(DATEPART(DAY,#date) AS FLOAT)/DATEPART(DAY,EOMONTH(#date)) * #amountDue AS AS [MonthToDateAmountDue]

Ms ACCESS: calculating past annual averages over varying date ranges

In a form on Ms ACCESS, a user can select a commodity (such as copper, nickel, etc.) from a list and a commodity price date from a list. A trailing 12 month average commodity price should then be calculated.
For example: the user selects Copper as commodity and February 1st 2010, 02/01/2010. I then want the average price to be calculated over the time period: [02/01/2009 - 02/01/2010].
I'm not sure how to write this in query form. This is the current incomplete code;
SELECT Avg(CommPrices.Price) AS Expr1,
FROM CommPrices
WHERE (((CommPrices.Commodity)=[Forms]![Tool Should Cost]![List243]))
AND CommPrices.DateComm = [Forms]![Tool Should Cost]![List55];
List243 is the list of commodities the user can select from, list55 is the list of dates the user can select. All data is obtained from the table CommPrices.
Note: the earliest dates in the column DateComm is 01/01/2008. So if the user selects a date for example 02/01/2008, then calculating the average over the past 12 months before 02/01/2008 won't be possible. I do want the code to still calculate the average using the dates available. (in the example it would just be the average over the past month)
Second Note: the column DateComm only has monthly dates for the first day of every month (e.g 01/01/2008, 02/01/2008, 03/01/2008). The dates listed in list55 can refer to different days in the month (e.g 03/16/2009), in that case I want the code to still calculate the past 12 month average using the closest commodity dates possible. So if the user selects date 03/16/2009, I want the code to calculate the 12 month average for 03/01/2008 - 03/01/2009.
For "integer" months it would be:
SELECT
Avg(CommPrices.Price) AS AveragePrice,
FROM
CommPrices
WHERE
CommPrices.Commodity=[Forms]![Tool Should Cost]![List243]
AND
CommPrices.DateComm = BETWEEN
DateSerial(Year([Forms]![Tool Should Cost]![List55]) - 1, Month([Forms]![Tool Should Cost]![List55]), 1)
AND
DateSerial(Year([Forms]![Tool Should Cost]![List55]), Month([Forms]![Tool Should Cost]![List55]), 1)

SQL Statement to return previous quarter balance

I'm trying to create a query that can return the previous quarter balance for a series of records.
I have financial data for accountid (acctid), fiscal year (fyear), fiscal quarter (fquarter) and fiscal period (fperiod) that I'm summing and tracking through a series of other queries that I'm dropping in to a temporary table, that data includes the net change for the period (nperiod), net change for the quarter (nquarter) and net change for the year (nyear). Net change for the period is only the account transactions in the period, net change for the quarter is the cumulative total of the transactions that appear in periods 1-3, 4-6, 7-9 and 10-12 respectively (amount from previous periods are not calculated in proceeding quarters, ie the net change for the quarter resets to $0 for periods 4, 7 and 9) and the net change for the year is the total cumulative sum. I'm now trying to create a sql statement that returns the previous quarter end balance.
So for periods 1-3 I need to write a separate select statements to return the ending balance for the previous year, for periods 4-6 I want them ALL to return the net change for the quarter from period 3, for 7-9 I want to return the net change for the quarter from period 6 for all records and for period 10-12 I want to return net change for the quarter from period 9.
Can I get some assistance because I have a gigantic query that returns the max period per quarter, then the nquarter amount associated with that period and then trying to do a where exists, but something tells me there's a better way to do it.
Thanks!

MDX , Calculate Number of days when the cummulative sum of Revenues from end of a month date match with the given debt amount

I have a financial cube and i have to calculate Daily Sales Outstanding as :
Number of Days between the selected month last date and the earliest transaction date when cummulative sum of Revenue from last date of the month till the date where sum revenue <= the debt amount for the date .
e.g
On 31/12/2009 my debt amount = 2,500,000
31-Dec-09 30-Nov-09 15-Oct-09 31-Oct-09
Revenue 1,000,000 1,000,000 500,000 1,0000
Cummulative sum of revenue 1,000,000 2,00,000 2,500,000 4,000,000
No of Days 31 30 16
On 15/Oct/09 cummulative revenue is 2,500,000 which equals my debt amount on that day
Count of Days = 31 + 31 + 16 = 76 Days.
In other words Sum Revenue from the selected date backwards until sum total equals or exeeds the total to date balance of the debtors.
Any help will be highly appreciated .
If i haven't explained clearly enough or if you need more information then please let me know.
Thanks in advance .
Shuchi.
Have you examined this blog: http://consultingblogs.emc.com/christianwade/archive/2006/04/30/MDX-Sprocs-and-Scripting_3A00_-An-Interesting-Example.aspx
He covers a few ways of approaching this, it sounds to me like a recursive problem, in that you need to 'walk backwards up along the calendar' adding up revenue, until you find the day where the added up revenue meets/exceeds the initial debt?
The above link should give you a few different approaches to tackle this, shout if you get stuck.