Date format in sas concatenate with a proc sql under conditions - sql

i have a macro_variable :%let date=201909
and table :
ID Sending-date item
1 15-jul-2019 A
2 23-sep-2019 B
3 12-sep-2019 A
4 1-jan-2019 B
5 5-feb-2019 B
What i'm wondering to do is to verify if there is an item sent in the month indicated in my date (09 september) and the two previous months (august and july) using a proc sql and without adding new variables.
the result_table expected is like this :
Month Year Number of items
9 2019 2
8 2019 0
7 2019 1
The biggest problem is how to convert the format of the date in the table like my macro_variable date.

Here's one method.
I used cutoff_date instead of date, because it helps differentiate the dates more easily.
Use INTNX() to do date calculations. In this case, I set the cutoff to be the end of cutoff_month and the start of two months prior. You may need to define that a bit more clearly to meet your needs but this works.
%let cutoff_date=201909;
proc sql;
create table want as
select month(sending_date) as Month, count(*) as num
from have
where sending_date between intnx('month', input("&cutoff_date.", yymmn6.), 0, 'e') and intnx('month', input("&cutoff_date.", yymmn6.), -2, 'b')
group by calculated Month;
quit;

Related

Convert integer years or months into days in SQL impala

I have two columns; both have integer values. One Representing years, and the other representing months.
My goal is to perform calculations in days (integer), so I have to convert both to calendar days, to achieve that, taking in consideration that we have years with both 365 and 366 days.
Example in pseudo code:
Select Convert(years_int) to days, Convert(months int) to days
from table.
Real Example:
if --> Years = 1 and Months = 12
1) Convert both to days to compare them: Years = 365 days; Months = 365 days
After conversion : (Years = Months) Returns TRUE.
The problem is when we have years = 10 (for example), we must take in account the fact that at least two of them have 366 days. The same with Months - we have 30 and 31 days. So I need to compensate that fact to get the most accurate possible value in days.
Thanks in advance
From integers to timestamp can be done in PostgreSQL. I do not have impala, but hopefully below script will help you getting this done using impala:
with
year as (select 2022 as y union select 2023),
month as (select generate_series(1,12) as m),
day as(select generate_series(1,31) as d )
select y,m,d,dt from (
select
y,m,d,
to_date(ds,'YYYYMMDD')+(((d-1)::char(2))||' day')::interval dt
from ( select
*,
y::char(4)|| right('0'||m::char(2),2) || right('0'||0::char(2),2) as ds
from year,month,day
) x
) y
where extract(year from dt)=y and extract(month from dt)=m
order by dt
;
see: DBFIDDLE
Used functions in this query and, a way, to convert them to imapala (remember I do not use that tool/language/dialect)
function
impala alternative
to_date(a,b)
This will convert the string a to a date using the format b. Using impala you can use CAST(expression AS type FORMAT pattern)
y::char(4)
Cast y to a char(4), Using imala you can use: CAST(expression AS type)
right(a,b)
Use: right()
\\
Use: concat()
generate_series(a,b)
This generates a serie of numbers from a to (an inclusing) b. A SQL altervative is to write SELECT 1 as x union SELECT 2 union SELECT 3, which generates the same series as generate_series(1,3) in PostgreSQL
extract(year from a)
Get the year from the datetime field a, see YEAR()
One special case is this one to_date(ds,'YYYYMMDD')+(((d-1)::char(2))||' day')::interval
This will convert ds (with datatype CHAR(8)) to a date, and then add (using +) a number of days (like: '4 day')
Because I included all days until 31, this will fail in Februari, April, June, September, November because those months do not have 31 days. This is corrected by the WHERE clause in the end (where extract(year from dt)=y and extract(month from dt)=m)

Sum of everything up to a date [duplicate]

This question already has answers here:
Calculate running total / running balance
(6 answers)
Closed 3 months ago.
I have a table with two columns, date and number of pieces, just like this:
pieces Date
100 2022-01-01
200 2022-02-01
300 2022-03-01
and so on.
I want to sum the number of pieces in the way that I increment the newest month, something like this:
january - 100 pieces
february - 300 pieces
march - 600 pieces
How would I do that?
What I've tried so far is make individual selects with one sum up to a point and then union with another, up to another point, but it seems counter productive.
select
sum(pieces)
, 'january' as month
from
table
where
date <= '2022-01-31'
union
select
sum(pieces)
, 'february' as month
from
table
where
date <= '2022-02-28'
union
select
sum(pieces)
, 'march' as month
from
table
where
date <= '2022-03-31'
say your dataframe is 'df'
step 1: create new column as "month" by 'month<-months(as.Date("Date"))" #new column will be created
step 2: use "group by" or "cumsum"

I need a count of serial numbers (last 6 months) that are under warranty for a failure rate report

My table has the following columns:
SerialNo
ProductNo
WarrantyBeginDt
WarrantyEndDT
I would like to get a monthly in warranty count looking back about 6 months. I know how to get a month by specifying in the where clause. Would like to have a query that generates the last 6 months with out having to specify the month in the where clause.
SELECT count(*)
FROM Supplemental_Warranty
WHERE WarrantyBeginDt <= '6-15-2022' AND WarrantyEndDt >= '6-15-2022'
How could I create a query that looks back 6 months from the current date?
UPDATED to add group by month for 6 months to get count by month.
This should give you 6 months worth of data using system date (subtract 6 months from today) and end date/time is now so you dont have to specify specific dates, just using date add functionality to subtract 6 months from stating date.
SELECT count(*), MONTH(WarrantyBeginDt) AS CountPerMonth
FROM Supplemental_Warranty
WHERE WarrantyBeginDt BETWEEN DATEADD(MONTH, -6, GETDATE()) AND GETDATE()
--if you have any flags or other logic to identify if it is underwarranty or not
AND IsUnderWarranty = 1
GROUP BY MONTH(WarrantyBeginDt)
NOTE: Not tested but this should do it depending on your SQL technology.

DB2 How to select dates for the previous 2 months

I am using Oracle SQL developer on DB2 and have a date field stored as an integer e.g. 20210401
I want to bring back results for the last 2 months and have tried this:
select * from table where date > add_months(sysdate, -2)
This is producing error 206 saying it is not valid in the context used.
Does anyone know how to convert the data column or have an easier way to filter for the last 2 months
Use this:
select *
from table
where date > INT (TO_CHAR (CURRENT TIMESTAMP - 2 MONTH, 'YYYYMMDD'));

convert month name in varchar to date so as to order by month [duplicate]

This question already has answers here:
Convert month name to month number in SQL Server
(14 answers)
Closed 9 years ago.
A table exists which stores month name in the form of string..
I want to order by year and month so as to get proper result.
year(string) Month(string) data
------------ ------------ ----
2012 August bigbox
2012 December samllbox
2013 April samll box
2012 September larg
I want to order by year and month. as in 2012,2013...
Jan,feb,march....
I am aware of the method of
case statement when
Month = 'january' THEN 1
Month - FEB THEN 2
But i do'nt want to use this as the procedure will be too big..
Your best option is to use the proper date type. Otherwise, create a table (inline or physical) to map your string months.
SELECT 1 AS month, 'January' AS strMonth
UNION ALL
SELECT 2, 'February'
UNION ALL
SELECT 3, 'March'
...
SELECT 12, 'December'
Then map this your table. See a demo
SELECT *
FROM TABLE
ORDER BY [year] DESC,
DATEPART(month,[Month] + ' 01 ' + CONVERT(VARCHAR(4),[YEAR]))
The above code will give you what you want , but i would strongly suggest you reconsider your design.
Right now you are reserving a string type field which would be at least 15 characters long. This field does not have any value than for display reasons. You could have a DATETIME field that would be much easier to short by (not having to do calculations there) and if you would like to display the name of the month you could use:
DATENAME ( month, DateField )