SQL datetime LIKE select - why do I need an extra %? - sql

Can someone explain to me why when I perform a LIKE select in SQL (T-SQL) on a varchar column I can do the following:
SELECT *
FROM Table
WHERE Name LIKE 'Th%'
to get names beginning with Th, but when I do the same on a datetime column I need a % before the year, like:
SELECT *
FROM Table
WHERE Date LIKE '%2013%'
to get dates in 2013. The datetimes are stored in yyyy-MM-dd hh:mm:ss format. I know I could use a DATEPART style query but I was just interested in why I need the extra % here.

The DATETIME is converted to a VARCHAR before the comparison, and there definitely is no guarantee that the conversion will be in the pattern you mention. DATETIME is not stored internally as a VARCHAR but as a FLOAT.

You should stop wondering because the syntax is not useful.
SELECT *
FROM Table
WHERE Date LIKE '%2013%'
Will give you a full table scan because the date will be converted to a varchar when comparing. In other words, don't do it !
Use this syntax instead:
SELECT *
FROM Table
WHERE Date >= '2013-01-01T00:00:00'
and Date < '2014-01-01T00:00:00'

If the Date field is in timestamp:-
SELECT *
FROM Table
WHERE year(Date) = '2013'

The sql server converts datetime to this format (Jan 1, 1900 9:20AM.)Because of that reason We need to use an extra %.
If you want to search the records start with month Jan
you can use following query for date time
SELECT *
FROM Table
WHERE Date LIKE 'Jan%'.
No need of extra '%'.

Related

Convert Number type to Date in postgres SQL

I have a numeric data in a column 20170930, need help in converting it into Date in PostgreSQL , tried multiple ways but non seems to work
You can convert to a string and then to a date:
select column::text::date
You can also express this using explicit cast() syntax:
select cast(cast(20170930 as text) as date)
Use one of the following :
SELECT cast(yourcol::varchar as date ) as dt1, yourcol::varchar::date as dt2
where dt1 and dt2 values of type date, and yourcol is a numeric value such as 20170930
Demo
The best thing is to change column datatype into Date type,
ALTER TABLE table_name
ADD column_name Date;
As shown above, PostgreSQL supports a full set of SQL date and time types, as shown in the table below. Dates are counted according to the Gregorian calendar. Here, all the types have a resolution of 1 microsecond / 14 digits except date type, whose resolution is day.
Please try below query
SELECT to_date(column::varchar,'YYYYMMDD')
For anybody who fell into my pitfall I tried this but my numeric was like a 'seconds past 01-01-1970 format' rather than YYYYMMDD
This worked
SELECT to_timestamp(yourcol) as numeric_column_now_date
from yourtable
see here
https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-ZONECONVERT

Convert TEXT to Date in SQL Server 2012

I have a TEXT in this format 31/10/15.
How do I convert this into a DATE format?
As I need to let the user search from data using a date range.
example: From 15/7/13 to 31/10/15
Or is there a way to so without converting to date?
You can use CONVERT() for this:
DECLARE #d VARCHAR(50) = '31/10/50'
SELECT CONVERT(DATE, #d,3)
Note that with a 2-digit year SQL Server will make the year start with '19' for 50 and up, and 49 and below will be '20'
Storing as a DATE field will allow easier comparisons, otherwise you'll have to perform this conversion at each step.
Use CONVERT; example:
SELECT [Date] = CONVERT(date, '31/10/15', 3);
And yes, it's possible to search dates in the same format as the examples you provide, but don't do that – use the proper data types in both your queries and your table columns.

Select Varchar as Date

I want to select a varchar field as a date field
For example a field has this value "30.12.2011 21:15:03"
and when i select this
select DATE from TABLE where DATE = '30.12.2011'
i get no result.
You ask about getting the date part of a timestamp field, but what your question is actually about is filtering on the date of a timestamp field. There is a much simpler method of accomplishing that: you can use the knowledge that all the possible timestamps on a specific date won't have any timestamps for different dates between them.
select DATE
from TABLE
where DATE >= '30.12.2011' and DATE < '31.12.2011'
Your edit explains that you haven't got a timestamp field at all. Nevertheless, a similar approach may still work:
select DATE
from TABLE
where DATE LIKE '30.12.2011 %'
Or the Firebird-specific
select DATE
from TABLE
where DATE starting with '30.12.2011 '
Assuming the field is a date field, use the DATE introducer combined with yyyy-mm-dd (or TIMESTAMP with time as well).
So use:
select datefield from sometable where datefield = DATE '2011-12-30'
Technically you can leave off the introducer, but it is 'correcter' in the light of the SQL standard.
Assuming a TIMESTAMP field, you won't get results unless the timestamp is (always) at 00:00:00.0000 (in which case it should have been a DATE instead).
For the comparison to work, you need to use either BETWEEN, eg:
select timestampfield from sometable
where timestampfield BETWEEN '2011-12-30 00:00:00.0000' AND '2011-12-30 23:59:59.9999'
or truncate the timestamp to a date (this may adversely effect performance if the timestamp is indexed, because then the index can no longer be used), eg:
select timestampfield from sometable
where CAST(timestampfield AS DATE) = '2011-12-30'
If the date is stored in a VARCHAR field (which in itself is a bad idea), there are several solutions, first is to handle it as date manipulation:
select varcharfield from sometable
where CAST(CAST(varcharfield AS TIMESTAMP) AS DATE) = '2011-12-30'
The double cast is required if you have a time-component in VARCHARFIELD as well. This assumes dates in the supported format listed below. If you use BETWEEN as above, you can use a single cast to timestamp)
The other solution (as suggested by hvd) is to treat it purely as string manipulation, for example:
select varcharfield from sometable
where varcharfield STARTING WITH '30.12.2011'
This has its own set of problems if you want to select ranges. Bottomline: use a real TIMESTAMP field!
Note that Firebird supports multiple formats:
yyyy-mm-dd, eg 2014-05-25 (ISO-8601 format, probably best to use as it reduces confusion)
dd.mm.yyyy, eg 25.05.2014
mm/dd/yyyy, eg 05/25/2014
mm-dd-yyyy, eg 05-25-2014
dd mmm yyyy, eg 25 MAY 2014 (+ variations with a -, . or / as separator)
mmm dd yyyy, eg MAY 25 2014 (+ variations with a -, . or / as separator)
select DATE from TABLE where cast(DATE as date) = '30.12.2011'
Date field is a timestamp
Here is the answere to my question:
CAST
(
SUBSTRING
(field FROM 1 FOR 2)
||'.'||
SUBSTRING
(field FROM 4 FOR 2)
||'.'||
SUBSTRING
(field FFROM 7 FOR 4)
AS DATE)
This took me 5 hours to find this out, maybe there should be a "-" instead of "." but it works.

how to skip sql timestamp to get records for specific date

I want to compare the date in my sql query and get the records for a specific date, but it is stored in timestamp format in postgres.
What kind of query could compare only date parts, since I want and skip the time part.
This Query will give you date like '2012/11/22' which you can use for date comparison.
SELECT CONVERT(VARCHAR(10),GETDATE(),111)
//OR simply
select CAST(GETDATE() as DATE)
You can see more formats here :- CAST and CONVERT (Transact-SQL)
Try this:
SELECT *
FROM tab
where date_col::DATE BETWEEN '2012-01-01'::DATE AND '2012-01-05'::DATE
SQL Fiddle DEMO

Between operation for date in SQLite database

I have a table student with the following columns:
no - integer
name - string
startdate - date
enddate - date.
Date format is MM/DD/YYYY.
I will give a date as input. Now I need a query the inputdate which found in between the start and end date.
For an example I will give 04/14/2012, then the query should return the 1st record as in the figure.
(because input date (04/14/2012) is found in between the 04/10/2012 to 04/20/2012)
Please help me.
The issue you are having is caused by your assumption that sqlite has a date/datetime type when in fact it doesn't.
I suggest you read the following http://www.sqlite.org/datatype3.html to have a better understanding of sqlite types.
The dates in the MM/DD/YYYY format are handled as TEXT by sqlite, and so those dates are compared as strings. For example, 02/01/2012 is considered bigger than 01/02/2012by sqlite if compared directly.
You will need to transform those dates to a format that can be string-compared. Here is an example:
sqlite> create table foo (d TEXT);
sqlite> insert into foo values ('02/01/2012');
sqlite> select substr(d, 7, 4) || substr(d, 1, 2) || substr(d, 4, 2) from foo;
20120201
You should post what you have tried so far.
There should be a between clause that you can use:
select * from table
where inputdate between startdate and enddate
Dates as a date type in SQLite don't exist. There are a number of approaches to dealing with dates - store them as integer seconds since 1 Jan 1970 (unixepoch) or store them as strings, but if you do, then you really need to store them in 'YYYY-MM-DD' format because that is what the date functions require as input.
Assuming you use the string format in the format I suggested then your query would look something like
SELECT * FROM Table WHERE Date(Inputdate) BETWEEEN Date(startDate) AND Date(EndDate);
(although you may want to format the output of the date columns to US date format with
SELECT Strftime("%m/%d/%Y",startDate) As StartDate ...
If you use seconds since 1970 its somewhat easier because the seconds just compare without needing the convert them to dates, although you still might want to output in US date format, so ...
SELECT Strftime("%m/%d/%Y",startDate) As StartDate ... FROM Table WHERE inputDate BETWEEN startDate and EndDate;
sqlite> select *from tbl_node where mydate between '2014-02-02' and '2014-02-06';
it show the output :-
1|1|123|456|12eb-ab|1|1|254|123|19|2014-02-03 16:00:44
2|1|123|456|12eb-ab|1|1|254|123|19|2014-02-03 16:01:03
3|1|123|456|12eb-ab|1|1|254|123|19|2014-02-03 16:00:57
4|1|123|456|12eb-ab|1|1|254|123|19|2014-02-03 16:00:34
Here mydate is column name in tbl_node;
we can also use from current time , using now.
sqlite> select *from tbl_node where mydate between '2014-02-02' and 'now';