Select rows within a date range in T-SQL - tsql

I have a set of rows, each with a date value, and I need to select rows that fall within a specific date range. How can I do this?
select * from table where convert(int,date_created) between //what should go here?
I want to select between '20-10-2010' and '22-10-2010'.
It keeps complaining about string to date conversion.

You need to use yyyymmdd which is the safest format for SQL Server
select * from table
where date_created BETWEEN '20101020' and '20101022'
Not sure why you had CONVERT to int there...
Note: if date_created has a time component that this fails because it assume midnight.
Edit:
To filter for the day 20 Oct 2010 to 22 Oct 2010 inclusive, if the date_created column has times, without applying a function to date_created:
where date_created >= '20101020' and date_created < '20101023'

Either don't convert the date_created to an int or use integers for your data values
I would leave the date_created as a date.
select * from table
where date_created between '20101020' and '20101022'

Related

How to filter date range data in timestamp with specific time from and to?

Assuming, I have data as below:
2021-09-10 09:00:00.000+00
2021-09-20 10:00:00.000+00
2021-09-20 11:00:00.000+00
I want to filter date range from 2021-09-20 10am to 2021-09-21 6pm? How can I write query to get it?
You need a range condition in the WHERE clause:
select *
from the_table
where the_column >= timestamp '2021-09-20 10:00:00'
and the_column < timestamp '2021-09-21 18:00:00'
timestamp literals are specified using the ISO standard for date/time literals. So the time part needs to be written in 24hour format.
It's not clear from your question if you want to include rows at 18:00:00 or if that should be the upper bound which is excluded. The above assumes the latter.
SELECT *
FROM table
WHERE column BETWEEN '2021-09-20 10:00:00'::timestamp
AND '2021-09-21 18:00:00'::timestamp;

When do I need to cast a value as a date?

I'm working myself through the Datacamp SQL track, and I'm currently working with date values. I've encountered two examples which seem contradictory to me.
-- Count requests created on January 31, 2017
SELECT count(*)
FROM evanston311
WHERE date_created::date='2017-01-31';
And:
-- Count requests created on February 29, 2016
SELECT count(*)
FROM evanston311
WHERE date_created>= '2016-02-29'
AND date_created< '2016-03-01';
Why do I need to cast the value as date in the first case but not the other?
As with most typed languages, you can rely on implicit type casting... until you can't.
Something like date_created >= '2016-02-29' Postgres can use the type of date_created to figure out how to implicitly cast '2016-02-29'. There's no ambiguity. But sometimes Postgres can't make a guess at all.
OTOH a function like date_part has multiple signatures date_part(text, timestamp) and date_part(text, interval). If you pass it a date string...
test=# select date_part('day', '2019-01-03');
ERROR: function date_part(unknown, unknown) is not unique
LINE 1: select date_part('day', '2019-01-03');
^
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
...Postgres cannot make a guess because the second string could be interpreted as either a timestamp or an interval type. You need to resolve this ambiguity.
# select date_part('day', '2019-01-03'::date);
date_part
-----------
3
Now that Postgres knows you're passing in a date it can correctly guess to use it as a timestamp.
Another reason is as a cheap way to truncate timestamps. In your example date_created::date = '2017-01-31' will truncate date_created to be a date and make the comparison work. Of course, date_created should already be a date...
You can use it on the value being compared if you're not sure if that value will be a date or a timestamp.
select * from table
where date_created = $1::date
This will work the same with '2019-01-02' or '2019-01-02 03:04:05'.
Which brings us to our final reason: making up for bad schemas. Like if date_created is actually a timestamp, or all too common, text. In that case you need to explicitly control how comparisons are made. For example, let's say we had text_created of type text that contained timestamps as strings: naught. And maybe some poorly formatted data crept in that has extra spaces on the end...
-- Text comparison compares the values exactly.
test=# select * from test where text_created = '2019-01-04';
date_created | time_created | text_created
--------------+--------------+--------------
-- Date comparison compares as dates ignoring the extra whitespace.
test=# select * from test where text_created::date = '2019-01-04';
date_created | time_created | text_created
--------------+--------------+--------------
| | 2019-01-04
See Chapter 10. Type Conversion in the Postgres docs for more.

How to get data between two date range in PostgreSQL?

I m querying data between two date range in PostgreSQL SQL but it does not give me expected result.
select
pi_serial,
amount_in_local_currency,
status,
proforma_invoice_date
from proforma_invoice
where created_by = 25
and proforma_invoice_date BETWEEN '03/01/2018' and '09/03/2018'
order by proforma_invoice_date
Now look at the query and column proforma_invoice_date. In this query i am searching data between 03/01/2018 and 09/03/2018. the date format is (DD/MM/YYYY) and it's character varying. The result i have got in this picture. it just give me the result according by the only day but not the whole date format. i have tried so many things date conversion, character varying to date. but i didn't get any expected result
Your Query is absolutely fine. just change it as follows
select pi_serial, amount_in_local_currency, status, proforma_invoice_date
from proforma_invoice
where created_by = 25
and to_date(proforma_invoice_date, 'DD/MM/YYYY') BETWEEN to_date('03/01/2018', 'DD/MM/YYYY') and to_date('09/03/2018', 'DD/MM/YYYY')
order by proforma_invoice_date

changing character into timestamp

I have two columns (date character varying, time character varying) in table VM. Now I want to merge these two columns and change the type as a timestamp. can anyone help me out to do this?
Or else
I want to separate data based on the year (2017, 2018). I used substring(date, '2018') command but it replies with 2017 data showing NULL instead of 2017 along with 2018 data.
You didn't tell us what exactly the contents of that table is, but something like this should work:
Add a new timestamp column (and please find a better name than "timestamp" or ts_column for it)
alter table the_table add ts_column timestamp;
Then you need to update the data
update the_table
set ts_column = to_timestamp(concat("date", ' ', "time"), 'yyyy-mm-dd hh24:mi:ss')
where "date" is not null;
The above assumes that the date stored in the column named "date" and the time stored in the column named "time" are formatted as ISO date and time values. If they are not, you need to adjust the parameter to the to_timestamp() function. For details on the format mask, please see the manual
Then drop the old columns:
alter table the_table drop "date", drop "time";
To extract the year from a date or timestamp column, use the extract function:
where extract(year from ts_column) = 2018
Note that the above will not be able to use an index on ts_column to speed up the query.
An alternative way of writing is:
where ts_column >= date '2018-01-01'
and ts_column < date '2019-01-01';
which would be able to use an index on ts_column

query to fetch records between two date and time

I have been using postgreSQL. My table has 3 columns date, time and userId. I have to find out records between the given date and time frame. Since date and time columns are different, 'BETWEEN' clause is not providing valid results
Combine the two columns into a single timestamp by adding the time to the date:
select *
from some_table
where date_column + time_column
between timestamp '2017-06-14 17:30:00' and timestamp '2017-06-19 08:26:00';
Note that this will not use an index on date_column or time_column. You would need to create an index on that expression. Or better: use a single column defined as timestamp instead.