Find the end date of a quarter given a date - date

I have the end dates of each quarter as the PK for a table, and I need to compare a date to see which quarter-ending value would be used in a calculation.
The Table looks like:
EndingDate Value
12/31/2012 $1,000
For example, given 3/1/2013 I would need to return 12/31/2012 and use that date to retrieve the $1,000 value.
Does anyone know what to use in MS Access 2007 to perform this? I tried:
DATEADD(dd, -1, DATEADD(qq, DATEDIFF(qq, 0, DATEINQUESTION), 0))
The calculation always uses the previous ending quarter's date, and the value associated with that date.

One way to do it would be with a combination of DMax() and DLookup(). For sample data in a table named [EndingBalances]
EndingDate Value
---------- -----
2012-09-30 900
2012-12-31 1000
2013-03-31 1100
2013-06-30 1200
2013-09-30 1300
2013-12-31 1400
the expression
DMax("EndingDate","EndingBalances","EndingDate<#2013-03-01#")
would return the date
2012-12-31
and therefore the expression
DLookup("Value","EndingBalances","EndingDate=#" & Format(DMax("EndingDate","EndingBalances","EndingDate<#2013-03-01#"), "yyyy-mm-dd") & "#")
would return the value
1000

I used this solution and it worked for me:
Format(DateAdd("s",-1,DateAdd("q",DateDiff("q","1/1/1950",Date()),"1/1/1900")),"Short Date")
It works so far..

Related

intck() giving negative value

I am new to SAS and I am having trouble with finding the difference between 2 dates.
I have 2 columns: checkin_date and checkout_date
the dates are in mmddyy10. format (mm/dd/yyyy).
I have used the following code:
stay_days= intck('day', checkin_day, checkout_day);
I am getting the right values for dates in the same month but wrong values for days that are across 2 months. For example, the difference between 02/06/2014 and 02/11/2014 is 5. But the difference between 1/31/2014 and 2/13/2014 is -18 which is incorrect.
I have also simply tried to subtract them both:
stay_day = checkout_day - checkin_day;
I am getting the same result for that too.
My entire code:
data hotel;
infile "XXXX\Hotel.dat";
input room_no num_guests checkin_month checkin_day checkin_year checkout_month checkout_day checkout_year internet_used $ days_used room_type $16. room_rate;
checkin_date = mdy(checkin_month,checkin_day,checkin_year);
informat checkin_date mmddyy.;
format checkin_date mmddyy10.;
checkout_date = mdy(checkout_month,checkout_day,checkout_year);
informat checkout_date mmddyy.;
format checkout_date mmddyy10.;
stay_day= intck('day', checkin_day, checkout_day);
Your problem is a typo - using wrong variables in intck() function. You are using variables "xxx_DAY" which is the DAY of month instead of the full DATE. Change to stay_day= intck('day', checkin_date, checkout_date);
Your data probably has the date values in the wrong variables. When using subtraction the order should be ENDDATE - STARTDATE. When using INTNX() function the order should be from STARTDATE to ENDDATE. In either case if the value in the STARTDATE variable is AFTER the value in the ENDDATE variable then the difference will be a negative number.
Perhaps you need to clean the data?
The only way to get -18 comparing 2014-01-31 and 2014-02-13 would be if you extracted the day of the month and subtracted them.
diff3 = day(end) - day(start);
which would be the same as subtracting 31 from 13.
Example using your dates:
data check;
input start end ;
informat start end mmddyy.;
format start end yymmdd10.;
diff1=intck('day',start,end);
diff2=end-start;
cards;
02/06/2014 02/11/2014
1/31/2014 2/13/2014
;
Results:
Obs start end diff1 diff2
1 2014-02-06 2014-02-11 5 5
2 2014-01-31 2014-02-13 13 13

Comparing date values for two columns

I have a column called PairDt, a string that contains a date value in the last 5 characters. I want to compare that date value with the date value in the Day column, which contains dates in the YYYY-MM-DD format.
PairDt Day
----------------------------------
DCS-CNY-Yunbi-42606 2016-08-24
DCS-CNY-Yunbi-42607 2016-08-25
DCS-CNY-Yunbi-42608 2016-08-26
DCS-CNY-Yunbi-42609 2016-08-27
DCS-CNY-Yunbi-42610 2016-08-28
How do I convert Day to a value?
I'm trying to isolate Date values in PairDt that does not match the date value in Days
This 5 digit number at the end of PairDt looks like number of days since December 30th 1899. To convert this number to date use DATEADD to add as many days. To convert a date to number, use DATEDIFF to calculate the number of days. Something like this code:
declare #PairDt varchar(50) = 'DCS-CNY-Yunbi-42606', #Day date = '2016-08-24'
select DATEADD(d, cast(right(#PairDt, 5) as int), '1899-12-30'), DATEDIFF(day, '1899-12-30', #Day)

SAS date swap year and day

I am working with a dataset containing a date variable with the format MMDDYY10..
The problem is, that the day, month and the year have been swapped.
The data set as it looks now:
Obs Date
1 11/01/1931
2 11/06/1930
3 12/02/2003
4 12/07/2018
What I would like is a date variable with the format DDMMYY10., or a similar:
Obs Date
1 31/01/2011
2 30/06/2011
3 03/02/2012
4 18/07/2012
Observation 1 is hence written as the 1st of November 1931, but really it is the 31st of January 2011.
Does anyone know how I can change this?
Looks like you read the original raw data using the wrong INFORMAT. Most likely you had data in YYMMDD format and you read it as MMDDYY. You can use the PUT() and INPUT() functions to attempt to reverse it.
data have ;
input date mmddyy10.;
newdate = input(put(date,mmddyy6.),yymmdd6.);
format date newdate yymmdd10. ;
put (date newdate) (=);
cards;
11/01/1931
11/06/1930
12/02/2003
12/07/2018
;;;;
Results:
date=1931-11-01 newdate=2011-01-31
date=1930-11-06 newdate=2011-06-30
date=2003-12-02 newdate=2012-02-03
date=2018-12-07 newdate=2012-07-18

TSQL update Datetime with Random Value between 2 Dates

What's the easiest way to update a table that contains a DATETIME column on TSQL with RANDOM value between 2 dates?
I see various post related to that but their Random values are really sequential when you ORDER BY DATE after the update.
Assumptions
First assume that you have a database containing a table with a start datetime column and a end datetime column, which together define a datetime range:
CREATE DATABASE StackOverflow11387226;
GO
USE StackOverflow11387226;
GO
CREATE TABLE DateTimeRanges (
StartDateTime DATETIME NOT NULL,
EndDateTime DATETIME NOT NULL
);
GO
ALTER TABLE DateTimeRanges
ADD CONSTRAINT CK_PositiveRange CHECK (EndDateTime > StartDateTime);
And assume that the table contains some data:
INSERT INTO DateTimeRanges (
StartDateTime,
EndDateTime
)
VALUES
('2012-07-09 00:30', '2012-07-09 01:30'),
('2012-01-01 00:00', '2013-01-01 00:00'),
('1988-07-25 22:30', '2012-07-09 00:30');
GO
Method
The following SELECT statement returns the start datetime, the end datetime, and a pseudorandom datetime with minute precision greater than or equal to the start datetime and less than the second datetime:
SELECT
StartDateTime,
EndDateTime,
DATEADD(
MINUTE,
ABS(CHECKSUM(NEWID())) % DATEDIFF(MINUTE, StartDateTime, EndDateTime) + DATEDIFF(MINUTE, 0, StartDateTime),
0
) AS RandomDateTime
FROM DateTimeRanges;
Result
Because the NEWID() function is nondeterministic, this will return a different result set for every execution. Here is the result set I generated just now:
StartDateTime EndDateTime RandomDateTime
----------------------- ----------------------- -----------------------
2012-07-09 00:30:00.000 2012-07-09 01:30:00.000 2012-07-09 00:44:00.000
2012-01-01 00:00:00.000 2013-01-01 00:00:00.000 2012-09-08 20:41:00.000
1988-07-25 22:30:00.000 2012-07-09 00:30:00.000 1996-01-05 23:48:00.000
All the values in the column RandomDateTime lie between the values in columns StartDateTime and EndDateTime.
Explanation
This technique for generating random values is due to Jeff Moden. He wrote a great article on SQL Server Central about data generation. Read it for a more thorough explanation. Registration is required, but it's well worth it.
The idea is to generate a random offset from the start datetime, and add the offset to the start datetime to get a new datetime in between the start datetime and the end datetime.
The expression DATEDIFF(MINUTE, StartDateTime, EndDateTime) represents the total number of minutes between the start datetime and the end datetime. The offset must be less than or equal to this value.
The expression ABS(CHECKSUM(NEWID())) generates an independent random positive integer for every row. The expression can have any value from 0 to 2,147,483,647. This expression mod the first expression gives a valid offset in minutes.
The epxression DATEDIFF(MINUTE, 0, StartDateTime) represents the total number of minutes between the start datetime and a reference datetime of 0, which is shorthand for '1900-01-01 00:00:00.000'. The value of the reference datetime does not matter, but it matters that the same reference date is used in the whole expression. Add this to the offset to get the total number of minutes between the reference datetime.
The ecapsulating DATEADD function converts this to a datetime value by adding the number of minutes produced by the previous expression to the reference datetime.
You can use RAND for this:
select cast(cast(RAND()*100000 as int) as datetime)
from here
Sql-Fiddle looks quite good: http://sqlfiddle.com/#!3/b9e44/2/0

Problem when extracting year and week number from string in PSQL

Let's say that I have a range of SQL tables that are named name_YYYY_WW where YYYY = year and WW = week number. If I call upon a function that guides a user defined date to the right table.
If the date entered is "20110101":
SELECT EXTRACT (WEEK FROM DATE '20110101') returns 52 and
SELECT EXTRACT (YEAR FROM DATE '20110101') returns 2011.
While is nothing wrong with these results I want "20110101" to either point to table name_2010_52 or name_2011_01, not name_2011_52 as it does now when I concanate the results to form the query for the table.
Any elegant solutions to this problem?
The function to_char() will allow you to format a date or timestamp to output correct the iso week and iso year.
SELECT to_char('2011-01-01'::date, 'IYYY_IW') as iso_year_week;
will produce:
iso_year_week
---------------
2010_52
(1 row)
You could use a CASE:
WITH sub(field) AS (
SELECT CAST('20110101' AS date) -- just to test
)
SELECT
CASE
WHEN EXTRACT (WEEK FROM field ) > 1 AND EXTRACT (MONTH FROM field) = 1 AND EXTRACT (DAY FROM field) < 3 THEN 1
ELSE
EXTRACT (WEEK FROM field)
END
FROM
sub;