Last 3 Months Where Statement - sql

I've got a SQL statement (SQL Server Management Studio) that I'm passing data into a where-statement into via a dashboard software. The users can select the year (2013 or now 2014) and also the month (which gets passes as a numeric value - so December = 12). I need to adjust the statement to where I get the last 3 months from the year/month they select. Before, b/c the SQL statement was only dealing with 2013 data, it was just the following:
YEAR(Main.ActivityDate) = '#Request.parmYear~'
AND (Month(Main.ActivityDate) Between ('#Request.parmMonth~'-2) and '#Request.parmMonth~')
Normally, parmYear = 2013 and then whatever month they select, it will grab 2 months prior through the current month.
Now, b/c it's January 2014, I need to to grab January 2014 + December 2013 + November 2013. I'm wondering how to adjust the statement to make this happen dynamically.
Thoughts?

I do not have a running SQL Server instance to test this solution but I would suggest constructing a date and using the built in functions to calculate the previous date as those already take into consideration the multiple years etc.
Declare #requestDate date = DATEFROMPARTS('#Request.parmYear', '#Request.parmMonth', 1);
...
AND Main.ActivityDate between #requestDate AND DATEADD(month, -2, #requestDate )
See this for more details.

I had a similar problem some time ago. My solution was something like this:
WHERE YEAR(Main.ActivityDate)*12 + YEAR(Month(Main.ActivityDate))
BETWEEN '#Request.parmYear~'*12+'#Request.parmMonth~'-2
AND '#Request.parmYear~'*12+'#Request.parmMonth~'
You could improve this solution sending one parameter as the result of '#Request.parmYear~'*12+'#Request.parmMonth~'.

There are two solutions for this.
Modify your current where statement and add a condition to check for this case.
Use DATEADD function. Present in comments and other answer(s).
Modifying your where to add Condition
Note: Minor error may exists since I need to check if January has month value of zero or 1.
Example:
WHERE
(
'#Request.parmMonth~'-2 < 1 AND
YEAR(Main.ActivityDate) = '#Request.parmYear~'-1 AND
Month(Main.ActivityDate) Between
(12+'#Request.parmMonth~'-2) AND 12
)
OR
(
YEAR(Main.ActivityDate) = '#Request.parmYear~'
AND (Month(Main.ActivityDate) Between
('#Request.parmMonth~'-2) and '#Request.parmMonth~'
)

Related

using where clause in SQL

I'm using postgre sql and I have a problem with where clause.
What I wanted to do was:
compare each month's data to that of previous month
select location where august to july ratio was lower than 0.7
Below is my code. I used cast as decimal because without that the result was just integers (either 0 or 1).
If I run the query, it does not return any results. It doesn't say error, but that there is no data where august < 0.7 (But there is! I checked in the original table without the where clause)
SELECT location
, round(cast(june as decimal)/may, 3) as june
, round(cast(july as decimal)/june, 3) as july
, round(cast(august as decimal)/july, 3) as august
FROM per_country
WHERE august < 0.7
Can you tell me what is wrong with my code? Thank you in advance
You cannot reuse an alias defined in the select clause in the where clause. You need to repeat the expression, or use a derived table (subquery, cte):
SELECT location
, round(june::numeric/may, 3) as june
, round(july::numeric/june, 3) as july
, round(august::numeric/july, 3) as august
FROM per_country
WHERE august::numeric/july < 0.7
Note that your existing query indicates of a bad design. You should not be storing each month in a separate table, for many reasons (scalability, efficiency, maintainability, ...). Instead, you should have each month on a separate row.

how to use year function and groupby to do a dynamic search?

Run a query that returns the number of trouble tickets in the VTM024… table, but only the ones created in the year 2015. Note: when setting the where criteria, use a function to extract the Year portion from the timestamp field.
Using the Year function in the first answer, write SQL that shows the number of trouble tickets created in each year dynamically, and do this using a “GROUP BY” clause in the SQL. It should return something like:
2012 10
2013 54
2014 111
etc
I was able to answer first question myself:
SELECT COUNT(CREATE_TIME) FROM TRACS_DW1.VTM024TROUBLE_TKT
WHERE EXTRACT (YEAR FROM CREATE_TIME) = 2015
I need help with 2nd question. I cant get groupby and extract functions together.
i have added a picture of my table.
Add EXTRACT (YEAR FROM CREATE_TIME) as year to your select query and group by the year field.

Have to make Calculated Measure NULL for the starting year of a dimension in SSAS Cube

I have a cube that maintains 4 years of data(Say 2014 to 2017(till now)). I have two calculate measure in which i have to make NULL for year 2014. Till now we are using SCOPE and making it NULL.
For example, below is the existing code for a calculated Measure to become NULL for year 2014.
SCOPE (DESCENDANTS([Calendar_Date].[Calendar_Date].[2014]));
[Measures].[Policy Retention Rate] = NULL;
END SCOPE;
Calendar_Date is a dimension and having only one Hierarchy "Calendar_Date".
Every year we have to change the value which is passed in scope. We have to change it to 2015 next year which is causing manual work.
So i have to automate it.
Kindly help me with this.
You can generate year dynamically. For example, get a member 3 years ago:
StrToMember('[Calendar_Date].[Calendar_Date].&[' + Format(Now(),'yyyy') + ']').Lag(3)
However I'm not sure if it's possible to use that within SCOPE statement.
P.S.: I'd remove the deprecated partitions on your DWH instead of MDXing your data.

BO Universe Designer - Where cluase for a year

I am trying to run a query within Business Objects Universe Designer and I need help with the 'Where' clause.
I want to search for all records that have a 4 digit year (the DB column is in YYYY) less than or equal to 3 years from the current year. So if the year is 2014, I would like to search for every record with a year less than or equal to 2011.
Here is my current where clause:
dbo.DB_TABLE.CATEGORY = 'Actual' and dbo.DB_TABLE.YR <= (convert (SMALLDATETIME, {fn CURDATE()})-3)
Under the 'Date' function, Universe Designer only has: convert (SMALLDATETIME, {fn CURDATE()})
Thanks in advance!!!
Since yr is just a number, you only need to extract the year from the current date:
dbo.DB_TABLE.YR <= datepart(year,{fn curdate()})-3
When writing a SQL statement in the SELECT or WHERE boxes in Designer, you are not limited to only using the functions available in the list box. Any SQL that is valid for the database can be used. The list box is only a helper, and lists commonly-used functions and statements.

Getting the range in SQL when given between

I am wondering if it's possible (without actually parsing the given string) to get the actual range (in terms of days, minutes or seconds) that is specified when you have an SQL statement like
[select 'x'
from dual
where date between to_date('20111113152049')
and to_date('20120113152049')]
I am working on a query where I'm given a string in the form of
"between to_date(A) and to_date(B)"
and would like to get that value in days to compare to a policy we let the user set so they don't enter a date range longer than say a week.
Assuming you're looking for a theoretical answer (that is: don't take this into production) this could work:
Prerequistes:
have three tables: days_seq(day_seq), month_seq(mth_seq) and year_seq(yr_seq)
days has the numbers 1...31, month 1..12, years 2011....?
Use te following query (I used access because I don't have proper RDBMS available here, keep in mind that MS-ACCESS/JET is forgiving in the use of the Dateserial function, that is, it doesn't break when you ask the dateserial for february, 30th, 2012)
SELECT Max(DateSerial(
[year_seq]![yr_seq]
,[month_seq]![mth_seq]
, [days_seq]![day_seq]))
-
Min(DateSerial(
[year_seq]![yr_seq]
,[month_seq]![mth_seq]
,[days_seq]![day_seq])) AS days
FROM days_seq, month_seq, year_seq
WHERE DateSerial(
[year_seq]![yr_seq]
,[month_seq]![mth_seq]
,[days_seq]![day_seq])
BETWEEN #2012-02-1# AND #2012-02-28#
The query basically produces a carthesian product of three tables which generates all possible days in months, months in a year for as many years as you have in the years table.
Bonus:
You could off-course generate a permanent Calendar table as X-Zero suggests.
table calendar([date])
INSERT INTO calendar
SELECT DISTINCT DateSerial(
[year_seq]![yr_seq]
,[month_seq]![mth_seq]
, [days_seq]![day_seq]))
FROM days_seq, month_seq, year_seq
You still have to pick your start year and your end year wisely. According to the Maya's an enddate of december 21st, 2012 will do.