I have a column called DUEDATE in my table called table1 which is a date in the format CCYYMMDD (This is a db2 database).
I want to retrieve DUEDATE records "within X days" of ANYGIVENDATE, so for example within 3 days of ANYGIVENDATE could mean all DUEDATE records that match dates 3 days before and after ANYGIVENDATE.
Although I can provide a CCYYMMDD argument I am struggling to compose the query.
I'm guessing I need to retrieve records
WHERE [DUEDATE] = [ANYGIVENDATE ± X DAYS]
(in CCYYMMDD format) ?
If you stored DUEDATE as the proper DATE data type, the query would simply be
...where DUEDATE between ANYGIVENDATE - X days and ANYGIVENDATE + X days
As it is, you could convert your values to the DATE data type, something like:
...where date(timestamp_format(varchar_format(DUEDATE),'YYYYMMDD'))
between date(timestamp_format(varchar_format(ANYGIVENDATE),'YYYYMMDD')) - X days
and date(timestamp_format(varchar_format(ANYGIVENDATE),'YYYYMMDD')) + X days
which might hurt performance in some cases. On IBM System i (formerly known as AS/400) you might try
...where date(timestamp_format(varchar(DUEDATE),'YYYYMMDD'))
between date(timestamp_format(varchar(ANYGIVENDATE),'YYYYMMDD')) - X days
and date(timestamp_format(varchar(ANYGIVENDATE),'YYYYMMDD')) + X days
because VARCHAR_FORMAT() there is only applicable to datetime data types. Alternatively you can calculate the boundary dates in the application and provide two decimal values in the WHERE clause:
...where DUEDATE between GIVENSTARTDATE and GIVENENDDATE
You'll need to compare DATE to DATE, so the database column and the input parameter need to be converted.
Or better, you should pass a DATE parm value into the stored proc and eliminate conversion for that value.
Or pass it in as a DATE, subtract/add X DAYS to it, then convert those resulting date values to DECIMAL or NUMERIC and use them to compare against the database value. Given the improper definition of the database column, that's possibly the best choice.
It's not totally clear what "within X days" means.
Related
Here trip 1 involves 2 activity_code in a single day and also concludes in a single day and most other activities are just single day but i have one trip that span over more than one day.
What could be the best possible way to store date range for that column that span more than one days.
Splitting the column into multiple begin date and end date just doesn't make sense as there would be many blank columns?
trip_id(pk,fk) Activity_code(pk,fk) date
1 a1 1st October 2015
1 a2 1st October 2015
2 a3 2nd -5th October 2015
Keep in mind that i need to search the activity_code on basis of month. such as list all the activity code that occur in October ?
Is it possible to insert a range of date in a single column or any other design solution ?
Is there any datatype that can represent the date range in single value ?
PS: oracle 11g e
Store the date ranges as FirstDate/LastDate or FirstDate/Duration.
This allows you to store the values in the native format for dates. Storing dates as strings is a bad, bad idea, because strings don't have all the built-in functionality provided for native date types.
Don't worry about the additional storage for a second date or duration. In fact, the two columns together are probably smaller than storing the value as a string.
Splitting the date into start date and end date would be ideal. Storing dates as strings is not recommended. If you store your dates as strings then there is a possibility of malformed data being stored in the column since a VARCHAR2 column will allow any value. You will have to build strong validations in your script while inserting the data which is unnecessary.
Secondly, you will not be able to perform simple operations like calculating the duration/length of the trip easily if both the start_date and end_date are stored in the same column. If they are stored in different columns it would be as simple as
SELECT trip_id, activity_code, end_date - start_date FROM trips;
suppose I have a table MyTable with a column some_date (date type of course) and I want to select the newest 3 months data (or x days).
What is the best way to achieve this?
Please notice that the date should not be measured from today but rather from the date range in the table (which might be older then today)
I need to find the maximum date and compare it to each row - if the difference is less than x days, return it.
All of this should be done with sqlalchemy and without loading the entire table.
What is the best way of doing it? must I have a subquery to find the maximum date? How do I select last X days?
Any help is appreciated.
EDIT:
The following query works in Oracle but seems inefficient (is max calculated for each row?) and I don't think that it'll work for all dialects:
select * from my_table where (select max(some_date) from my_table) - some_date < 10
You can do this in a single query and without resorting to creating datediff.
Here is an example I used for getting everything in the past day:
one_day = timedelta(hours=24)
one_day_ago = datetime.now() - one_day
Message.query.filter(Message.created > one_day_ago).all()
You can adapt the timedelta to whatever time range you are interested in.
UPDATE
Upon re-reading your question it looks like I failed to take into account the fact that you want to compare two dates which are in the database rather than today's day. I'm pretty sure that this sort of behavior is going to be database specific. In Postgres, you can use straightforward arithmetic.
Operations with DATEs
1. The difference between two DATES is always an INTEGER, representing the number of DAYS difference
DATE '1999-12-30' - DATE '1999-12-11' = INTEGER 19
You may add or subtract an INTEGER to a DATE to produce another DATE
DATE '1999-12-11' + INTEGER 19 = DATE '1999-12-30'
You're probably using timestamps if you are storing dates in postgres. Doing math with timestamps produces an interval object. Sqlalachemy works with timedeltas as a representation of intervals. So you could do something like:
one_day = timedelta(hours=24)
Model.query.join(ModelB, Model.created - ModelB.created < interval)
I haven't tested this exactly, but I've done things like this and they have worked.
I ended up doing two selects - one to get the max date and another to get the data
using the datediff recipe from this thread I added a datediff function and using the query q = session.query(MyTable).filter(datediff(max_date, some_date) < 10)
I still don't think this is the best way, but untill someone proves me wrong, it will have to do...
I want to calculate the percentages using date fields in my SSRS report.
I have two date fields :
eg I have 3 columns in my matrix
monthly target,
monthly completed and
percentage
Due date field count 10
completed date count 5
percentage 50%
for example
=Sum(Fields!Completeddate.Value)/Sum(Fields!duedate.Value)*100
however, this will not work for date fields.
Can anyone help?
Thanks in advance
The most straight-forward way to do this would be to add this field to your stored procedure (since it represents a column in your matrix) instead of trying to calculate it in SSRS.
Your SQL statement may look like this:
SELECT #CompletedDate, #DueDate, CAST(DateDiff(day, GetDate(), #CompletedDate) AS FLOAT)/CAST(DateDiff(day, GetDate(), #DueDate) AS FLOAT) * 100 AS INT) AS [Percentage]
The exact implementation will depend on how exactly you're using this value, but the point is that you can use the DateDiff() function to determine how many days apart two dates are, and with that information, you can find a percent difference. Once you've calculated this, you can assign it to a matrix column like you would any other value.
I would like to have a date and time column in my table. The main purpose of having these 2 columns is to be able to return query results like:
Number of treatments done in the period November 2011.
Number of people working in shifts between 00:01 and 08:00 hours.
I have two tables, which have the following attributes in them(among others):
Shift(day, month, year)
Treatment(start_time, date)
For the first table- Shift, query results need to return values in
terms of (ex: December 30,2012)
For the second table, start_time needs to have values like 0001 and
0800(as I mentioned above). While, date can return values like
'November 2011'.
Initially I thought using the date datatype for declaring each of the day/month/year/date variables would do the job. But this doesn't seem to work out. Should I use int, varchar and int respectively for day, month and year respectively? Also, since the date variable does not have component parts, will date datatype work here? Lastly, if I use timestamp data type for the start_time attribute, what should be the value I enter in the insert column- should it be 08:00:00?
I'm using SQL Server 2014.
Thank You for your help.
AFAIK it is better to use one column by type of DateTime instead of two columns which hold Date and Time separately.
Also you could simply query this column either by Date or Time by casting it to corresponding type :
DECLARE #ChangeDateTime AS DATETIME = '2012-12-09 16:07:43.937'
SELECT CAST(#ChangeDateTime AS DATE) AS [ChangeDate],
CAST(#ChangeDateTime AS TIME) AS [ChangeTime]
results to :
ChangeDate ChangeTime
---------- ----------------
2012-12-09 16:07:43.9370000
Long title, easy meaning:
How is it possible to extract from a date like "2014-04-04 10:47:30.000", which is stored in one column, it's components like year, month and day?
I'm not interested in the time.
For example, I have a table called "Incidents". Inside the table we got a column called "IncidentID" and a column called "ReportingDate", in which dates like the above-mentionend are stored. Let's say we have about 50k Incidents, therefore we have also 50k dates.
A year has 365 days. I want to query for the count of the Incidents, which were reported on different dates - for instance on the 5th of October 2013.
So: How can I get the components of the date and put them into another table while having own columns for the components and how can I query for the Incidents as well?
I guess at first I have to change the datatype of the date from DATETIME to DATE, but I'm not quite sure how to go further. May anyone help me while giving me a code and explains me what it does for a sql-noob? :-)
To achieve this
I want to query for the count of the Incidents, which were reported on
different dates - for instance on the 5th of October 2013.
you haven't do this:
I guess at first I have to change the datatype of the date from
DATETIME to DATE, but I'm not quite sure how to go further.
Just query
SELECT
IncidentID
FROM incidents
WHERE ReportingDate >= '20131005'
AND ReportingDate < '20131006'