Max(Date) not working for nvarchar in SQL Server - sql-server-2008

I have a column name Endtime of type nvarchar(50) and i am trying to get the max(Endtime) by using the below query:
select COALESCE(CONVERT(nVARCHAR(50), MAX(EndTime), 103), '-') AS EndTime from dbo.vwJobHistory
The results are fine as long as Year is same (12/31/2015) but as soon as i put some data with year (01/22/2016) , the query still shows the Max. Date of 2015 instead of 2016.
I have tried Max(cast(endtime as DateTime)) but this also gives conversion error
How can I resolve this? Thanks in advance.

I can't find an error in your above query, but here's an alternative way how you could write the query:
select top 1 COALESCE(CONVERT(nVARCHAR(50), EndTime, 103), '-') AS EndTime
from dbo.vwJobHistory
order by endtime desc
Update 1 (clarifying table structure):
It is currently unclear if your datetime data is currently stored inside a nvarchar(50) field or if you want to cast your datetime data as nvarchar(50).
Could you run the following query and update your question with the result?
SELECT
COLUMN_NAME, DATA_TYPE, col.CHARACTER_MAXIMUM_LENGTH
FROM INFORMATION_SCHEMA.COLUMNS col WHERE TABLE_NAME LIKE 'vwJobHistory'
Could you also post a sample row from your table using
SELECT endtime FROM dbo.vwJobHistory
Update 2 (convert string to datetime, apply sort on converted field)
Taken from your comment, it seems your date strings are stored with SQL format 109, so let's try to convert the nvarchar back to datetime, apply sort to it and output the result:
SELECT * FROM (
SELECT
convert(datetime, EndTime, 109) endtimeconverted,
*
FROM vwJobHistory
) xyz
ORDER BY endtimeconverted DESC

Related

MySQL - sort by date column which is stored as text in format MMYYYY

I'm trying to sort by a column called date which stores various dates in format MMYYYY (for example, 122020, 102019, etc.).
The SQL query that I have looks like this:
SELECT `date`, `invested` FROM `savings` WHERE `id` = 123 ORDER BY STR_TO_DATE(`date`, "%m%Y") ASC but this query does not sort the output correctly.
Any ideas on how to sort it properly?
Important note: Reclassifying/modifying the column's type is not an option at this point.
EDIT: My current SQL query, which is described above, sorts the dates like this: 102019, 102020, 112019, 112020. But my goal is to have it like this: 102019, 112019, 102020, 112020.
Thank you
Try separating the date string into two parts (year and month), cast each part as integer, and then ordering by that number:
SELECT
date_,
invested
FROM
savings
WHERE
id = 123
ORDER BY
CAST(SUBSTRING(date_, 3, 6) AS UNSIGNED),
CAST(SUBSTRING(date_, 1, 2) AS UNSIGNED)
;
This will do the job :) refer to this DB Fiddle for clarification.

mysql date conversion returns null converting certain months

I have this query (take a look on between dates):
SELECT user_name, COUNT(*) AS 'COUNT'
FROM user_records
WHERE date_created between (STR_TO_DATE('11/24/2020','%m/%d/%y'))
and (STR_TO_DATE('12/26/2021','%m/%d/%y'))
GROUP BY user_name ;
The select is between dates:
startDate: (STR_TO_DATE('11/24/2020','%m/%d/%y'))
finishDate: (STR_TO_DATE('12/26/2021','%m/%d/%y'))
This query will return something because there are records on year 2020
the problem is when i change the month of the finishDate, i tried with:
finishDate: (STR_TO_DATE('1/26/2021','%m/%d/%y')) = null
finishDate: (STR_TO_DATE('01/26/2021','%m/%d/%y')) = null
finishDate: (STR_TO_DATE('10/26/2021','%m/%d/%y')) = null
It just makes no sense... im using mysql community 8.0.20
Since the problem only occurs in the finsihDate perhaps this could be helpful.
SELECT user_name, COUNT(*) AS 'COUNT'
FROM user_records
WHERE date_created between (STR_TO_DATE('11/24/2020','%m/%d/%y'))
and (DATE_ADD(STR_TO_DATE('11/24/2020','%m/%d/%y'), INTERVAL 367 DAY))
GROUP BY user_name ;
Of course you should check for relevant errors or warnings in MySQL server logs, that could explain the problem for finsihDate.
********UPDATE SOLUTION:
for some unknown reason my db IDE shows the date with this format "$DAY/$MONTH/$YEAR" even if insert the right DATE MYSQL FORMAT ("$YEAR-$MONTH-$DAY)
i got the following warnings:
And this is the final query that worked but your solution did worked as well:
SELECT user_name, COUNT(*) AS 'COUNT'
FROM user_records
WHERE date_created between '2020-11-24' AND '2021-01-24'
GROUP BY user_name ;
The problem with your query is the date format. Lowercase '%y' matches a two digit year. So, only the first two characters from 2021 are used for the year -- and you have the wrong year.
But, that is not the real problem. You don't need str_to_date(). Just use properly formatted date literals.
Assuming that the dates are stored correctly as date data types, then you can simply use:
SELECT user_name, COUNT(*) AS COUNT
FROM user_records
WHERE date_created between '2020-11-24' and '2021-12-26'
GROUP BY user_name ;
If date_created is stored as a string, then fix your data model so it is either a date or datetime. Dates should not be stored as strings.

Showing data by ignoring the time portion from the date

I am using JasperReports/iReport to do my report. I have wrote a query for the client to key in the date,but there is 1 issue, the date is come along with the time portion.
How can I ignore the time portion for the client to key in the data?
date rate
2/2/2014 12:56:21.0000 PM ABC
4/2/2014 12:56:21.0000 PM EFG
5/2/2014 12:56:21.0000 PM HIJ
...
I have assign from customer to design with the parameter of year,month, and day.In other words, when the customer key in the year,month,and day,
the data will show this way:
2/2/2014 12:56:21.0000 PM ABC
The query i have wrote is show below:
select date,rate
from mytable
where rownum=1
and tran_dt<=(select date
from mytable
where year(date)=$P{year}
and month(date)=$P{month}
and day(date)=$P{day}
)
order by
date
I'm using pl/sql query...
SQL SERVER :
Use This
select convert(varchar(10), '2011-02-25 21:17:33.933', 120)
Like This
Select DATE_FORMAT(date,'%y-%m-%d'),rate from mytable
where rownum=1 and tran_dt<=(select tran_dt from bi01_trandetail where
year(date)=$P{year} and month(tran_dt)=$P{month} and day(tran_dt)=$P{day})
order by date
MYSQL
USE
DATE_FORMAT(date,'%y-%m-%d')
Select DATE_FORMAT(date,'%y-%m-%d'),rate from mytable
where rownum=1 and tran_dt<=(select tran_dt from bi01_trandetail where
year(date)=$P{year} and month(tran_dt)=$P{month} and day(tran_dt)=$P{day})
order by date
OR
SELECT DATE('2003-12-31 01:02:03');
'2003-12-31'
Select date(date),rate from mytable
where rownum=1 and tran_dt<=(select tran_dt from bi01_trandetail where
year(date)=$P{year} and month(tran_dt)=$P{month} and day(tran_dt)=$P{day})
order by date
Your New Query:
select date,rate
from mytable
where rownum=1
and tran_dt<=(select DATE_FORMAT(date,'%y-%m-%d')
from mytable
where year(date)=$P{year}
and month(date)=$P{month}
and day(date)=$P{day}
)
order by
date
MYSQL DATE FUNCTION
You have to ways, from the DDBB...
With PL/SQL check the TO_CHAR doc, http://www.techonthenet.com/oracle/functions/to_char.php, (and this SO question, ;D: How to format a Date variable in PLSQL).
Your query will be:
SELECT TO_CHAR(date, 'MM/DD/YYYY'), rate from mytable ...
With MySQL (NOTE: I leave the MySQL answer because I answered first with it because it wasn't specified RMDB)
MySQL DATE_FORMAT function, getting only what you want:
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-format
from the web as example:
SELECT DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y');
-> 'Sunday October 2009'
Testing the case you proposed:
SELECT DATE_FORMAT('2014-03-02 23:45:35', '%e/%c/%y %H:%i:%s %p');
-> 2/3/14 23:45:35 PM
With no time portion:
SELECT DATE_FORMAT('2014-03-02 23:45:35', '%e/%c/%y');
-> 2/3/14
Your query will be:
select DATE_FORMAT(date, '%e/%c/%y') ,rate from mytable ...
... and the other way is with the date functions from your server scripts, but that is another history and I'd need what language you use, XD
Thank you all for the reply, i have found the way to solved this question.
Let i share the query,
select rate,trunc(date) as EFFDT from mytable
Where rownum=1
and
date <= to_date(:DAY||'/'||:MTH||'/'||:YR, 'DD/MM/YYYY')
order by date desc

Find results in certain date range

I am trying to only grab records that fall in a certain date range. The problem is that the timestamp and the date are stored as a string in the same cell. I want to only grab rows with a date that falls betweed 2013-05-01 and 2013-05-03.
date (stored as string)
2013-05-01T23:19:44
2013-05-02T23:19:40
2013-05-06T23:19:46
2013-05-06T23:15:17
mysql
SELECT * FROM table WHERE date BETWEEN 2013-05-01 AND 2013-05-03
Try
SELECT *
FROM table1
WHERE STR_TO_DATE(`date`,'%Y-%m-%d') BETWEEN '2013-05-01' AND '2013-05-03'
SQLFiddle
As #FreshPrinceOfSO absolutely correctly noted no index will be used in that case
SELECT * FROM table1
WHERE STR_TO_DATE(SUBSTRING(`date`,1,10),'%d-%m-%Y')
BETWEEN '2013-05-01' AND '2013-05-03'
The string is almost valid syntax for a datetime. Thus, an alternative, if perhaps slower method is to replace the 'T' with a space and then cast it to a datetime.
SELECT * FROM table1 WHERE
CAST(REPLACE(`date`, 'T', ' ') AS DATETIME)
BETWEEN '2013-05-01' AND '2013-05-03';
SELECT * FROM table
WHERE date('yourdate') BETWEEN date('2013-05-01') AND date('2013-05-03')

How to solve this "cursor" type query in MySQL?

I have the following data in my table. BTW ... this is a DD/MM/YYYY format:
Date
18/09/2012
17/09/2012
13/09/2012
11/09/2012
10/09/2012
09/09/2012
25/08/2012
24/08/2012
The result what I want are:
Date
18/09/2012
13/09/2012
11/09/2012
09/09/2012
25/08/2012
The rule:
It starts from the latest date (18/09/2012) and check the next one down (17/09/2012). If there is a date then removed that from the list because it requires to have 1 day apart. Then goes to 13/09/2012 and then check 12/09/2012 and didn't find and then move to next one so on and so on. Basically you can't have date close each other (min 1 day apart).
Now I can do this on cursor if it's on TSQL however since I'm working on MySQL, is there any such thing in MySQL? Or perhaps any sub-queries approach that can solve this query?
I'm appreciated your feedback.
Try this solution -
SELECT date FROM (
SELECT
date, #d := IF(#d IS NULL OR DATEDIFF(#d, date) > 1, date, #d) start_date
FROM
dates,
(SELECT #d:=null) t
ORDER BY
date DESC
) t
WHERE start_date = date
The subquery finds out start days (18, 13, 11...), then WHERE condition filters records. Try to run the subquery to understand how it works -
SELECT
date, #d := IF(#d IS NULL OR DATEDIFF(#d, date) > 1, date, #d) start_date
FROM
dates,
(SELECT #d:=null) t
ORDER BY
date DESC
SELECT
"MyTable1"."Date"
FROM
"MyTable" AS "MyTable1"
LEFT JOIN "MyTable" AS "MyTable2" ON
ADDDATE("MyTable1"."Date", INTERVAL 1 DAY) = "MyTable2"."Date"
WHERE
"MyTable2"."Date" IS NULL
ORDER BY
"MyTable1"."Date" DESC
As long as I know about mysql query will be quit tricky and buggy if some how you manage to write the one. I suggest go for cursor, here is the syntax of the cursor,
here is the syntax of the cursor