select
traceid, CONVERT(varchar, CONVERT(VARCHAR(12),serialnumber)) serialnumber,
product_prod_week,
LEFT(product_prod_week,4)+'00' + month(dateadd(wk,right(product_prod_week,2) -1,
LEFT( product_prod_week,4) + '/01/01')) as product_prod_month,
isnull(product_prod_date,s.century_proddate) product_prod_date
from
mq m join serialdate s on m.product_prod_week= s.century_serdat
/*This part is restricting view to 36 months only*/
where
LEFT( product_prod_week,4)+'00' +month(dateadd(wk,right(product_prod_week,2) -1,
LEFT( product_prod_week,4) + '/01/01')) between substring(Replace(DATEADD(month,-37, DATEADD(month,-1,convert(date,getdate()))),'-',''),1,6)
and substring(replace(DATEADD(month,-1,convert(date,getdate())),'-',''),1,6)
The above is a view. view_mq. I have been banging my head over this from last many hours but can't find the issue.
select count(* )from view_mq
select COUNT(*) from view_mq where isdate(product_prod_date)=0
gives me this error -
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
Where is the conversion happening? I don't understand.
serialdate table is has century_proddate column as datetime.
product_prod_date in mq is datetime format.
Rest are in char/varchar type.
Related
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
I have 2 date fields of dateTime data type each.
One is called PhaseEnd and the other is PhaseStart.
We would like to substract PhaseStart from PhaseEnd to get the number of months between the two.
When I run the following query:
SELECT (CASE WHEN PhaseEnd IS NOT NULL THEN round((PhaseEnd - PhaseStart)/30,1)
ELSE round((getdate() - PhaseStart)/30,1) END) Months from tblT_PHASES
I get Implicit conversion from data type datetime to int is not allowed. Use the CONVERT function to run this query.
Any idea how to fix this?
use datediff
select
case
when PhaseEnd is not null then
round(datediff(day, PhaseStart, PhaseEnd)/30,1)
else
round(datediff(day, PhaseStart, getdate())/30,1)
end as Months
from tblT_PHASES
or
select
round(
datediff(day, PhaseStart, isnull(PhaseEnd, getdate())) / 30
, 1) as Months
from tblT_PHASES
I'm curious what the right way is to construct a query where the rows are pulled based on a timestamp that represents a specific month. Given that different months have different numbers of days, is there a way to generate a query that always gives you the rows where the timestamp contains the current month so that the results would only include the current month?
Do you mean something like this
SELECT * FROM tbl WHERE
MONTH(timesp) = MONTH(NOW()) AND
YEAR(timesp) = YEAR(NOW());
You can use the FROM_UNIXTIME() function:
SELECT *
FROM tableName
WHERE MONTH(FROM_UNIXTIME(timestampField))==6
Just use MONTH:
select *
from foo
where month_column = MONTH(getdate())
and year_column = YEAR(getdate())
Try this sql.
select *
from yourtable
where yourdatefield>=DATE_SUB(CURDATE(),INTERVAL 1 MONTH);
You're looking for something like this:
SELECT * FROM table where MONTH(date_row) = $month;
If you have an index on your date field, then this is efficient (T-SQL syntax, the idea applieas to any RDBMS though)
SELECT
*
FROM
tableName
WHERE
dateTimeField
BETWEEN
-- build the string 'YYYY-MM-01', cast back as a datetime
CAST(
CAST(YEAR(GETDATE()) AS varchar) + '-' + CAST(MONTH(GETDATE()) AS varchar) + '-01'
AS datetime
)
AND
-- add one month, subtract one day
DATEADD(mm, 1,
-- build the string 'YYYY-MM-01', cast back as a datetime
CAST(
CAST(YEAR(GETDATE()) AS varchar) + '-' + CAST(MONTH(GETDATE()) AS varchar) + '-01'
AS datetime
)
) - 1
Of course any other method to get two datetime values in the right range would work.
SQL Server has LEFT(CONVERT(varchar, GETDATE(), 120), 8) + '01' to convert a datetime to string, other Db servers have their own functions to do the same. Maybe you can calculate the two values in the calling application more easily - how you get them, is not the point.
The point is that BETWEEN can use an index, whereas the other solutions that work with WHERE MONTH(dateTimeField) = 6 will trigger a table scan, which is about the slowest operation you can do on a table.
Lets say I have a table that contains the following - id and date (just to keep things simple).
It contains numerous rows.
What would my select query look like to get the average TIME for those rows?
Thanks,
Disclaimer: There may be a much better way to do this.
Notes:
You can't use the AVG() function against a DATETIME/TIME
I am casting DATETIME to DECIMAL( 18, 6 ) which appears to yield a reasonably (+- few milliseconds) precise result.
#1 - Average Date
SELECT
CAST( AVG( CAST( TimeOfInterest AS DECIMAL( 18, 6 ) ) ) AS DATETIME )
FROM dbo.MyTable;
#2 - Average Time - Remove Date Portion, Cast, and then Average
SELECT
CAST( AVG( CAST( TimeOfInterest - CAST( TimeOfInterest AS DATE ) AS DECIMAL( 18, 6 ) ) ) AS DATETIME )
FROM dbo.MyTable;
The second example subtracts the date portion of the DATETIME from itself, leaving only the time portion, which is then cast to a decimal for averaging, and back to a DATETIME for formatting. You would need to strip out the date portion (it's meaningless) and the time portion should represent the average time in the set.
SELECT CAST(AVG(CAST(ReadingDate AS real) - FLOOR(CAST(ReadingDate as real))) AS datetime)
FROM Rbh
I know that, in at least some of the SQL standards, the value expression (the argument to the AVG() function) isn't allowed to be a datetime value or a string value. I haven't read all the SQL standards, but I'd be surprised if that restriction had loosened over the years.
In part, that's because "average" (or arithmetic mean) of 'n' values is defined to be the sum of the values divided by the 'n'. And the expression '01-Jan-2012 08:00' + '03-Mar-2012 07:53' doesn't make any sense. Neither does '01-Jan-2012 08:00' / 3.
Microsoft products have a history of playing fast and loose with SQL by exposing the internal representation of their date and time data types. Dennis Ritchie would have called this "an unwarranted chumminess with the implementation."
In earlier versions of Microsoft Access (and maybe in current versions, too), you could multiply the date '01-Jan-2012' by the date '03-Mar-2012' and get an actual return value, presumably in units of square dates.
If your dbms supports the "interval" data type, then taking the average is straightforward, and does what you'd expect. (SQL Server doesn't support interval data types.)
create table test (
n interval hour to minute
);
insert into test values
('1:00'),
('1:30'),
('2:00');
select avg(n)
from test;
avg (interval)
--
01:30:00
I've got a table with 9 million records. Each one has a "BirthDate" field that is stored as a varchar. I'm trying to select all where the birthdate is 25 years or less (all people 25 or under). It's failing, because somewhere in this monstrosity of a table, there is an invalid value.
select COUNT(*) from LeadSplit where CAST(LeadSplit.Birthdate as datetime) > DATEADD(yy, -26, getdate()) and Birthdate is not null
The error is:
Msg 242, Level 16, State 3, Line 1
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
I'm at a loss as to how to find the row with the invalid value, and also, how to deal with it. I would like to just ignore it or fix it.
You could try to find the offending rows by doing something like:
SELECT (some ID), Birthdate
FROM dbo.YourTable
WHERE ISDATE(Birthdate) = 0
This might not work for all cases - but it might give you a starting point.
The error you are getting is that one or more of the dates cannot be parsed given the DateFormat setting.
Set DateFormat MDY
GO
Select Count(*)
From LeadSplit
Where Case
When IsDate(BirthDate) = 0 Then 0
When BirthDate >= DateAdd(yyyy,-25,CURRENT_TIMESTAMP) Then 1
End = 1
Try to use CONVERT instead of CAST and explicit specify date format. MSDN Article about CAST and CONVERT