Get the last 24 months of data from Netezza database - netezza

I want to pull the last 24 months of data but excluding the most 2 recent quarters (current quarter and last quarter) from our netteza database. The format of date field in the database is like this: YYYY-Q-MM
2015411 = Year=2016 Quarter=4 month= 11
2013108 = Year=2013 Quarter=1 month= 8
The expected time frame should be data from October 2014 to September 2016. We are using calendar year Jan to Mar is Q1 and Apr to Jun is Q2 etc. This is the query i am using but it pulls everything for the last 27 months but i only want the last 24 months but excluding the most 2 recent Quarters.
select * from myTable where substring (month_key,1,4) || substring (month_key, 6,7) || ''01'' > CURRENT_DATE - INTERVAL ''27 months''

You can utilize the built in quarter evaluation.
The query below highlights the desired values
select add_months(to_date(to_char(to_date(to_char(current_date,'YYYYQ'),'YYYYQ')-1,'YYYYQ'),'YYYYQ'),-24) as "24 months prior to 2 quarters ago"
,to_date(to_char(to_date(to_char(current_date,'YYYYQ'),'YYYYQ')-1,'YYYYQ'),'YYYYQ') "2 quarters ago"
This is it in your example:
select * from myTable
where date_value between select add_months(to_date(to_char(to_date(to_char(current_date,'YYYYQ'),'YYYYQ')-1,'YYYYQ'),'YYYYQ'),-24)
and to_date(to_char(to_date(to_char(current_date,'YYYYQ'),'YYYYQ')-1,'YYYYQ'),'YYYYQ')

Related

MS-SQL: "Desc" seems to have no effect on "order by" if used in a subquery [duplicate]

This question already has answers here:
Create a view with ORDER BY clause
(10 answers)
sql 'select top 1' without 'order by' from view with 'top 100 percent ... order by ...' declaration gives unexpected results [duplicate]
(1 answer)
Why use Select Top 100 Percent?
(10 answers)
How to sort within a sql view
(4 answers)
ORDER BY in a Sql Server 2008 view
(7 answers)
Closed 7 months ago.
Yes, the right thing is to use "order by" in the calling query instead of the subquery, but not in this case. I want to order a list in descending order of date, but I don't want to show the actual date field itself in the output. I just want to show the "spoken" date, e.g. Thu 21 Jul, Wed 20 Jul, etc.
with list1 as
(
select
top 100 percent
convert(varchar,Sign_in,23) [Date],
datename(d,Sign_in)+' '+
left(datename(m,Sign_in),3)+' '+
left(datename(dw,Sign_in),3) [Day],
string_agg(trim(uid),' ') Staff
from
attendance.staff with(nolock)
where
Sign_in >= getdate() - 14
group by
datename(d,Sign_in)+' '+
left(datename(m,Sign_in),3)+' '+
left(datename(dw,Sign_in),3),
convert(varchar,Sign_in,23)
order by
[Date] DESC
)
select
Day,
Staff
from
list1
Whether I have the "desc" or not, the list is always sorted in ascending order. If I take the subquery out and run it separately, "desc" or "asc" behave as expected. But used inside the subquery, "desc" has no effect.
Example output:
8 Jul Friday John Mary Amy
11 Jul Monday Mary Jack
12 Jul Tuesday John Mary
13 Jul Wednesday Karen Ian
14 Jul Thursday Martin Suzanne Mary John
15 Jul Friday etc. etc. etc.
18 Jul Monday etc. etc. etc.
19 Jul Tuesday etc. etc. etc.
20 Jul Wednesday etc. etc. etc.
21 Jul Thursday etc. etc. etc.
I want the above to list in descending order from 21 Jul to 8 Jul
WITH List1 AS (
SELECT Sign_In [Date],
string_agg(trim(uid),' ') [Staff]
FROM Attendance
WHERE Sign_In >= GetDate()-14
GROUP BY Sign_In
)
SELECT FORMAT([Date], 'dd dddd MMMM'), -- 07 Thursday July
[Staff]
FROM List1
ORDER BY [Date] Desc
~ Assuming Sign_In is a DateTime or something similar, if it is a Date, you can omit the Convert. ~ (Convert removed per OP's comment)
And unless you have good reason, never use (NOLOCK).
EDIT 2:
Actually, given that Sign_In is a Date, there's no longer need for the CTE.
SELECT format(Sign_In, 'dd dddd MMMM') [Date],
string_agg(trim(uid), ' ') [Staff]
FROM Attendance
WHERE Sign_In >= GetDate()-14
GROUP BY Sign_In
ORDER BY Sign_In DESC

How to get the data in snowflake for past 24 months in snowflake

I have the data for the current month in Snowflake which I am extracting with the below mentioned query
select distinct HPOLICY
, ANNUALPREMIUMAMOUNT
, year(dateadd(year, 0, CURRENT_DATE))
, month(dateadd(month, 0, CURRENT_DATE)) yearmonth
from hub_test
I want to extrapolate this data to the past 24 months which means get the same data with Sep 2019, Aug 2019 and so on till past 24 months.
That query is get all time distinct data, and put a fake current year/month column on it.
If you where doing something like:
select distinct HPOLICY
,ANNUALPREMIUMAMOUNT
,date_part('year', date_column) as year
,date_part('month', date_column) as month
from hub_test
where date_column >= date_trunc('month',CURRENT_DATE());
you would have the current months data, if date_column was the date_of the data in the row.
Therefore to get the last 24 months you would alter that to:
select distinct HPOLICY
,ANNUALPREMIUMAMOUNT
,date_part('year', date_column) as year
,date_part('month', date_column) as month
from hub_test
where date_column >= dateadd('month',-24, date_trunc('month',CURRENT_DATE()));

Query last 12 months of data where year and month are separate columns

I'm trying to figure out a way to query the last 12 completed months of data, so it would go up to last month and ignore this month.
I've done this before when the table had a date column, but this new table I'm working with separates the date into two month and year columns.
How would I go about this in SQL Server 2012?
Thanks in advance.
SAMPLE DATA:
CalendarYear CalendarMonth TotalSales
2014 3 35.00
2014 4 220.00
2015 2 243.00
2015 5 17.93
2015 6 216.36
2015 10 370.93
2015 12 350.00
2016 1 116.75
2016 2 13.78
DESIRED OUTPUT (assuming current time is in February 2016):
CalendarYear CalendarMonth TotalSales
2015 2 243.00
2015 5 17.93
2015 6 216.36
2015 10 370.93
2015 12 350.00
2016 1 116.75
I've assumed the Day part is always the 1st of the month.
WHERE
CONVERT(DATETIME, CalendarYear + '-' + CalendarMonth + '- 01') >= DATEADD(mm, -12, GETDATE())
The above assumes the columns are strings. Below I've done a version where the columns are numbers.
WHERE
CONVERT(DATETIME, CAST(CalendarYear AS NVARCHAR(4)) + '-' + CAST(CalendarMonth AS NVARCHAR(2)) + '-01') >= DATEADD(mm, -12, GETDATE())
You can just apply same code/logic to year and month you want data.
where to_date(year || month, 'YYYYMM')
between add_months(trunc(sysdate, 'MM'), -12) and trunc(sysdate)

PIVOT Table Date & Year wise data display sql server 2005

this is my query
SELECT *
FROM (SELECT CurDate, YEAR(CurDate) AS orderyear, Warranty_Info
FROM eod_main where year(CurDate)>=2009 and year(CurDate)<=2011) AS D
PIVOT(SUM(Warranty_Info) FOR orderyear IN([2009],[2010],[2011])) AS P
the above query return data but CurDate return date it is is return multiple date for same month.
i want that SUM(Warranty_Info) should return only once for every month and year
output should look like
Month 2009 2010 2011 2012 2013
----- ---- ---- ---- ---- -----
1 10 0 11 32 98
2 20 10 21 11 44
3 0 224 33 77 31
some kind of problem is there in my query and that is why it is returning multiple data for same month like
please help me to have the right query. thanks
Instead of using CurDate as the full date with year, month and day, I would suggest using the Month() function to return the numeric value of each month. This will allow you to group by month instead of the full date:
SELECT dateMonth, [2009],[2010],[2011]
FROM
(
SELECT month(CurDate) dateMonth,
YEAR(CurDate) AS orderyear, Warranty_Info
FROM eod_main
where year(CurDate)>=2009
and year(CurDate)<=2011
) AS D
PIVOT
(
SUM(Warranty_Info)
FOR orderyear IN([2009],[2010],[2011])
) AS P;
See SQL Fiddle with Demo

Need help with a SQL query selecting date ranges from a table of period quarters

I have a table called Periods that looks like this
PeriodID | PeriodYear | PeriodQuarter
7 | 2009 | 1
8 | 2009 | 2
9 | 2009 | 3
10 | 2009 | 4
11 | 2010 | 1
12 | 2010 | 2
Each row in the table represents 1 of the 4 quarters of the year (like 3-monthly school terms). E.g. The first row represents Period 1 of 2009 (i.e. the date range 1 Jan 2009 - 31 March 2009.
Now I need to write a query that selects rows/periods from the above table, where the period occurs between 2 date ranges, as per the following pseudocode.
select *
from Periods
where Period is between #startDate and #endDate
The query will be used inside a table-valued function called dbo.GetPeriodsFromDateRange, and #startDate and #endDate are parameters to the function.
I'm stuck and can't figure out how to do it. Please help. This applies to T-SQL (MS SQL Server 2000/2005)
Try
select *
from Periods
where dateadd(qq,PeriodQuarter-1,dateadd(yy,PeriodYear -1900,0))
between #startDate and #endDate
A seek instead of a scan is possible:
SELECT *
FROM Periods
WHERE
PeriodYear BETWEEN Year(#startdate) AND Year(#enddate)
AND PeriodYear * 4 + PeriodQuarter
BETWEEN Year(#startdate) * 4 + DATEPART(Quarter, #startdate)
AND Year(#startdate) * 4 + DATEPART(Quarter, #enddate)
Explanation:
I'm composing a new, scaled integer from two component pieces, the year and the quarter, treating each combination of year and quarter as a single number.
Imagine instead that I had done it this way:
AND PeriodYear + (PeriodQuarter - 1) / 4.0
BETWEEN Year(#startdate) + (DATEPART(Quarter, #startdate) - 1) / 4.0
AND Year(#startdate) + (DATEPART(Quarter, #enddate) - 1) / 4.0
Calling my original expression "Mult" and this new one "Div", here are some years and quarters and what those expressions will evaluate to:
Year Qtr Div Mult
2009 1 2009.00 8037
2009 2 2009.25 8038
2009 3 2009.50 8039
2009 4 2009.75 8040
2010 1 2010.00 8041
2010 2 2010.25 8042
2010 3 2010.50 8043
So now if we run a WHERE clause against these rows:
WHERE Div BETWEEN 2009.25 AND 2010.00
You can see how it will return the correct rows. The Mult version really does exactly the same, just scaling the year up instead of the quarter down. The reason I used it is because integer math and multiplication are faster than fractional math and division.
The reason that I use two conditions starting with just the year is to make the query sargable. We want to do the seek based on just year, which isn't possible if we're multiplying it by 4 or doing other math on it. So we get the scan into only the right years first, then fine tune it to eliminate any quarters that shouldn't be in the result.
Another option is to add a calculated column and put an index on it. This wouldn't require any changes to code inserting or updating (as long as they properly use column lists), but would let you do regular range math as you desire.
I would be tempted to add 2 further columns to the table...
StartDate and EndDate - these will store the date that each period starts and ends (i.e. in your example StartDate=1st Jan 2009 and EndDate=31st March 2009)
This will give you more flexibility if the quarters are defined differently than you have suggested.
If you do this, then the query become fairly simple...
select *
from Periods
where #startDate<Periods.StartDate and #endDate>Periods.EndDate
This is assuming you only want to include Periods which are completely encapsulated between #StartDate and #EndDate. If you want Periods that overlap then try something like...
select *
from Periods
where #EndDate>Periods.StartDate and #StartDate<Periods.EndDate

Resources