SQL Calculation for ASP.NET - asp.net

In my SQL database I have a column that contains a fiscal year value. Fiscal Year start from Oct 1st to Sept 30th of the following year. For example the current fiscal year is 2011-2012 or "2011". I need a calculation to pull dates from my database.
I have a column in my table that contains dates (i.e. 05/04/2012), I need a calculation that will pull the dates for the selected fiscal year? So when I need to see the data for the date 02/14/2003, then I would need the fiscal year of 2002.
This all ties into my ASP.NET page, where a user selects which fiscal year they want to view and a gridview appears with the information requested. So, if I choose fiscal year 2010, the data pulled into the gridview should be all records from 10/01/2010 to 09/30/2011. Thanks for the help, I have yet to try anything because I am not sure where to begin (sql newbie).

You can find the fiscal year by adding three months:
year(dateadd(month,3,'2011-09-30'))
So to select all entries in Fiscal year 2011, try:
select *
from YourTable as yt
where year(dateadd(month,3,yt.TransactionDt)) = 2011

I assume you are using SqlParameters to send data to the SQL Server. Then:
int fiscal_year = 2002;
SqlParameter fyStart = new SqlParameter("#FiscalYearStart",
SqlDbType.DateTime);
fyStart.Value = new SqlDateTime(fiscalYear, 10, 01);
SqlParameter fyEnd = new SqlParameter("#FiscalYearEnd",
SqlDbType.DateTime);
fyEnd.Value = new SqlDateTime(fiscalYear+1, 10, 01);
Then you can pass these two params to an Stored Procedure for example, and to query the table with
WHERE date BETWEEN #FiscalYearStart AND #FiscalYearEnd
N.B. FiscalYearEnd should be 10-Oct-YEAR+1, as it will be represented as YYYY-10-01T00:00:00, or will include the whole 30 Sept.

You could query for it:
SELECT *
FROM YourTable
WHERE YourTableDate >= CAST(#FiscalYear AS CHAR(4)) + '-10-01'
AND YourTableDate < CAST(#FiscalYear + 1 AS CHAR(4)) + '-10-01';
or, if you need the flexibility, you could alternatively have a table of date ranges which join to fiscal years. This gives you the ability to have multiple fiscal year definitions for, say, multiple tenants or companies, or allows the definition to change without changing your queries. You could then join to this table as needed to filter your results.
CompanyID FiscalYear StartDate EndDate
1 2010 2010-10-01 2011-09-30
1 2011 2011-10-01 2012-09-30
2 2010 2010-01-01 2011-12-31
2 2011 2011-01-01 2012-12-31
SELECT *
FROM YourTable t
INNER JOIN FiscalYear y
ON y.FiscalYear = t.FiscalYear
WHERE t.YourTableDate >= y.StartDate AND t.YourTableDate < DATEADD(d, 1, y.EndDate);

Related

Window function lag() in trigger uses default instead of previous value

I'm trying to create an SQLite trigger to update balance for a particular account code.
accounts table :
CREATE TABLE accounts (
year INTEGER NOT NULL,
month INTEGER NOT NULL CHECK(month BETWEEN 1 AND 12),
amount REAL NOT NULL CHECK(amount >= 0),
balance REAL,
code INTEGER NOT NULL
);
When a new row is inserted I want the balance value of the new row to reflect OLD balance + NEW amount. But this trigger does not recognize the lagging balance value and I cannot figure out why:
CREATE TRIGGER trg_accounts_balance
AFTER INSERT ON accounts
BEGIN
UPDATE accounts
SET balance = (
SELECT
lag(balance, 1, 0) OVER (
PARTITION BY code
ORDER BY month
) + NEW.amount
FROM accounts
)
WHERE rowid = NEW.ROWID;
END;
If I insert one row per month, I expect my data to look like:
year
month
amount
balance
code
2022
1
100.0
100.0
100
2022
2
9.99
109.99
100
But I get:
year
month
amount
balance
code
2022
1
100.0
100.0
100
2022
2
9.99
9.99
100
What am I doing wrong?
The query:
SELECT
lag(balance, 1, 0) OVER (
PARTITION BY code
ORDER BY month
)
FROM accounts
returns as many rows as there are in the table and SQLite picks the first (whichever it is) to return it as the result so that it can use it to add NEW.amount.
There is nothing that links this value to the specific row that was inserted.
Instead, use this:
CREATE TRIGGER trg_accounts_balance
AFTER INSERT ON accounts
BEGIN
UPDATE accounts
SET balance = COALESCE(
(
SELECT balance
FROM accounts
WHERE code = NEW.code
ORDER BY year DESC, month DESC
LIMIT 1, 1
), 0) + NEW.amount
WHERE rowid = NEW.ROWID;
END;
The subquery returns the previous inserted row by ordering the rows of the specific code descending and skipping the top row (which is the new row).
See the demo.

Fiscal Month Start Dates

I have a fiscal Month End date column. Based on this column I will have to calculate 12 month prior fiscal start date, 24 month prior fiscal start date and so on.
I cannot use add_months function here as below are the fscl month end dates. When a user chooses 01-JUL-2017, the 12 months prior date should start at 03-JUL-16.
If I use add months the date range would change to be 01-JUL-2016 to 01-JUL-2017 but I need it to be 03-JUL-2017 to 01-JUL-2017.
FISCAL MONTH END DATES
30-JAN-16
27-FEB-16
02-APR-16
30-APR-16
28-MAY-16
02-JUL-16
30-JUL-16
27-AUG-16
01-OCT-16
29-OCT-16
26-NOV-16
28-JAN-17
25-FEB-17
01-APR-17
29-APR-17
27-MAY-17
01-JUL-17
Considering that your table has all the dates in the sequence, You can use the LAG function with parameter 11 (i.e. 11th previous date in the sequence).Take the user input from the where clause as a bind Variable.
( WHERE TO_CHAR(DT,'DD-MON-YY') = :curr_fiscal_end_dt )
SELECT Prev_fisc_start_date FROM
(
SELECT DT, LAG(DT, 11 ) OVER ( ORDER BY DT ) + 1 Prev_fisc_start_dt FROM
Your_table
) WHERE TO_CHAR(DT,'DD-MON-YY') ='01-JUL-2017';

how to show sum(cost) and revenue from two tables and display per month

i have two tables:
table 1:
Expense cost
Posting Date
table 2:
Employee cost
Rvenue
Billing Date
Totalcost = Expense cost + Employee cost
Pofit Revenue - TotalCost
i have to display the report like so. It should show data per month according to year lets say 2011, (i know how to filter by year)
Totalcost | Revenue | Profit
jan
feb
mar
apr
may
jun
jul
aug
sep
oct
nov
dec
I'm having a tough time fugring out the query.
The problem is how can i display the data in report viewer table
Simplest way would be to combine the data to form a single data-table that will act as a data-source for the report.
You can join both tables at database side - for example,
SELECT
t1.Month,
t1.ExpenseCost + t2.EmployeeCost AS TotalCost,
t2.Revenue,
t2.Revenue - t1.ExpenseCost - t2.EmployeeCost AS Profit
FROM
Table1 t1
INNER JOIN Table2 t2 ON t1.Year = t2.Year and t1.Month = t2.Month
WHERE
t1.Year = #Year /* parameter to filter for a year */
or you can combine the data at front end either by using data relation or more simply by using LINQ over data tables - for example
var query = from t1 in table1.AsEnumerable()
join t1 in table2.AsEnumerable()
on t1.Field<string>("Month") equals t2.Field<string>("Month")
select new
{
Month = t1.Field<string>("Month"),
TotalCost = t1.Field<Decimal>("ExpenseCost") + t2.Field<Decimal>("EmployeeCost"),
Revenue = t2.Field<Decimal>("Revenue"),
// similarly compute profit
};

SQL Group Distinct Count

I have the following table
User ID Start Date End Date
-------------------------------------
John Doe Mar 11 2011 May 28 2011
Robret S Mar 21 2011 Jun 29 2011
Tina T Feb 01 2011 August 20 2011
I want to show how many people I have available for the past 6 months, even if the month has no people. How can this be possible. I know I have to do grouping and use distinct count.
Expected Output:
February = 1 Resource
March = 3 Resources
April = 3 Resources
May = 3 Resources
June = 2 Resources
July = 1 Resource
August = 1 Resource
With Calendar As
(
Select Cast('20110501' As DateTime) As [Date]
Union All
Select DateAdd(m,-1,[Date])
From Calendar
Where [Date] > DateAdd(m,-5,'20110501')
)
Select DateName(m, C.Date) + ' ' + Cast(Year(C.Date) As char(4))
, Case Count(*)
When 1 Then Cast(Count(*) As varchar(10)) + ' Resource'
Else Cast(Count(*) As varchar(10)) + ' Resources'
End
From Calendar As C
Left Join MyTable As T
On C.Date Between T.StartDate And T.EndDate
Group By C.Date
Results:
December 2010 | 1 Resource
January 2011 | 1 Resource
February 2011 | 1 Resource
March 2011 | 1 Resource
April 2011 | 3 Resources
May 2011 | 3 Resources
You will need the existing data records for the last 6 months, so that you can merge the two sets of data. You can generate the last 6 months in a CTE and do a left join with your data. That will allow you to show the last 6 months even if you have no data.
I don't think you can do what you want using a "simple" select statement (even using GROUPing etc.) The following is off the top of my head, so you'll have to experiment with it a little, and preferably read Joe Celko's excellent SQL for Smarties book.
You need to create a second table that contains all of your months (start/end dates). You only need one table for all types of similar queries, and it must contain all the months in the date ranges your interested in querying:
CREATE TABLE months (id, start DATE, end DATE);
INSERT INTO months (id, start, end)
values ( (1, 2011-01-01, 2011-01-31),
(2, 2011-02-01, 2011-02-28), ...);
You then LEFT OUTER JOIN from your user table to this month table. That will give you a row for each user for each month they were available, which you can GROUP as required:
SELECT months.id, COUNT(user.id)
FROM months LEFT OUTER JOIN users
ON user.start_date < months.end
AND user.end_date > months.start
GROUP BY months.id;
Hope that helps.
WITH resources AS (
SELECT
Date = DATEADD(month, v.number, [Start Date])
FROM atable t
INNER JOIN master.dbo.spt_values v ON v.type = 'P'
AND v.number BETWEEN 0 AND DATEDIFF(month, t.[Start Date], t.[End Date])
)
SELECT
Month = DATENAME(month, Date),
ResourceCount = CAST(COUNT(*) AS varchar(30)) +
CASE COUNT(*) WHEN 1 THEN ' Resource' ELSE ' Resources' END
FROM resources
WHERE Date > DATEADD(month, -6, DATEADD(day, -DAY(GETDATE()), GETDATE()))
GROUP BY YEAR(Date), MONTH(Date), DATENAME(month, Date)
ORDER BY YEAR(Date), MONTH(Date)

How to find Sum of a field per month in a particular in sqlite3

I have a table created by the following statement in sqlite3
CREATE TABLE IF NOT EXISTS expenses
(
id INTEGER PRIMARY KEY,
name TEXT,
amount REAL,
category INT NOT NULL,
date TEXT
)
date entered in the database is in the format yyyy-mm-dd.
How to do i write a sqlite3 select statement such that i get sum of expenses per month in a given year. In other words if the user enters year 2011 I should get total expenses per month in 2011.
month total_amount
1 200
2 10
3 1500
4 340
5 124
SELECT SUM(amount) AS total_amount,
Strftime("%m", `date`) AS 'month'
FROM expenses
WHERE Strftime("%Y", `date`) = '2011'
GROUP BY Strftime("%m", `date`);
check out SQLite Date And Time Functions
(edited)

Resources