SQL date conversion for 8 char value with 00 as days - sql

I have been having trouble trying to figure out how to properly convert the data. In its current form it is varchar and the data is as follows:
19260200,
19770900,
20030400,
20120300,
20020500,
So as you can see I have the year and months, but have no values for dates. When I try to insert it into SQL field formatted as datetime i get errors. Anyone know how i can fix this? I am working with a DB of 700,000 records so I need to be able to write some code to address it and not just manually go through and change.
Thanks in advance for the help!!!

INSERT dbo.destination(date_column)
SELECT dt FROM
(
SELECT dt = CASE
WHEN src_date_column LIKE '%00' THEN
STUFF(src_date_column, 8, 1, '1')
ELSE src_date_column
END
FROM dbo.source
) AS x
WHERE ISDATE(dt) = 1;
To address comments:
AS x is just an alias. A derived table needs to be called something. If you just say:
SELECT x FROM (SELECT x = 1);
You get this unhelpful error:
Msg 102, Level 15, State 1
Incorrect syntax near ';'.
But not if you say:
SELECT x FROM (SELECT x = 1) AS y;
As for your other question, you can simply add other columns to the inner SELECT, e.g.:
INSERT dbo.Citation(PatentNo, Citation, CitedBy, CitationDate)
SELECT PatentNo, Citation, WhoCitedThis, dt
FROM
(
SELECT PatentNo, CitationSource, WhoCitedThis, dt = CASE
WHEN CitationDate LIKE '%00' THEN STUFF(CitationDate, 8, 1, '1')
ELSE CitationDate
END
FROM dbo.CitationSource
) AS x
WHERE ISDATE(dt) = 1;
Now, you need to decide what you want to do with invalid dates, such as 20120231 or 20120399. Those are just left behind. My first recommendation would be to make that a proper date or datetime column, and reject bad dates from getting into the system in the first place.

You can try something like this:
cast(left(val, 6)+'01') as date)
That is, insert a valid day value into the string and do the conversion.

Related

How to test a condition in a sql case statement on numbers

I would like to substitute all the values that are greater or equal to 10 with an empty string with a SQL CASE statement on my Microsoft SQL Server 2017. However, I am getting an error that reads:
Msg 102, Level 15, State 1, Line 13
Incorrect syntax near '>'.
Though there are some questions similar to my question, I can not find an answer that is specifically answering my question. For example this question here how to use > = condition in sql case statement?. I have also tried a dynamic query with a temporal table and this did not help.
Here is my code with the table definition and the test data as well as the actual query that I am running.
--table definition with two columns
declare #table table
(
person nvarchar(20),
digit decimal(10,2)
)
--insert test data with two records
insert into #table
select 'titimo', 9.51
union
select 'neriwo', 12.25
--the requirement is to not show the digit value if it is greater or equal to 10, but rather display an empty field.
--so, this is my select statement to meet this requirement that is failing
--with error message 'Incorrect syntax near >'
select
person,
case digit
when digit >= 10 then ''
else digit
end 'digit'
from #table
From my select statement above, I am expecting this output:
person digit
------ -----
titimo 9.51
neriwo
However, the output is not being generated because of the error message that I am experiencing.
You had a syntax error in your case. More over you cannot mix datatypes so you need to cast digit to varchar or change '' i.e. to null.
select
person,
case
when digit >= 10 then ''
else cast(digit as varchar(20))
end 'digit'
from #table
Your case is not formatted correctly - here's one option -
(also, you can't select text and numbers in the same column - so I casted your number to text... tweak to fit your needs)
select
person,
case when digit >=10 then ''
else CONVERT(VARCHAR(10), digit)
end 'digit'
from #table

how to convert the output of sub query into numeric

select rptName
from RptTable
where rpt_id in (
select LEFT(Reports, NULLIF(LEN(Reports)-1,-1))
from repoAccess1
where uid = 'VIKRAM'
)
this is my sql query In which i have use the sub query to access selected field
in this sub query returns
select LEFT(Reports, NULLIF(LEN(Reports)-1,-1))
from repoAccess1
where uid = 'VIKRAM'
Returns
1,2
that means the query should be like
select rptName
from RptTable where rpt_id in (1,2)
But i m getting this error
Msg 8114, Level 16, State 5, Line 1
Error converting data type nvarchar to numeric.
could anyone tell me ow to modify to get exact ans
It's a little hard to tell without the concrete table definitions, but I'm pretty sure you're trying to compare different data types to each other. If this is the case you can make use of the CAST or the CONVERT function, for example:
SELECT
[rptName]
FROM [RptTable]
WHERE [rpt_id] IN
(
SELECT
CONVERT(int, LEFT([Reports], NULLIF(LEN([Reports]) - 1, -1)))
FROM [repoAccess1]
WHERE [uid] = 'VIKRAM'
)
UPDATE: Since you have updated your question: The LEFT function returns results of either varchar or nvarchar data type. So the resulting query would be
SELECT
[rptName]
FROM [RptTable]
WHERE [rpt_id] IN('1', '2')
Please note the apostrophes (is this the correct term?) around the values. Since [rpt_id] seems to be of data type int the values cannot implicitly be converted. And that's where the aforementioned CAST or CONVERT come into play.
If I understand correctly, the subquery is returning a single row with a value of '1,2'. This is not a number, hence the error.
Before continuing, let me emphasize that storing values in comma delimited string is not the SQL-way of doing things. You should have one row per id, with proper types and foreign keys defined.
That said, sometimes we are stuck with other people's really bad design decisions. If this is the case, you can use LIKE:
select rptName
from RptTable r
where exists (select 1
from repoAccess1 a
where a.uid = 'VIKRAM' and
',' + a.reports + ',' like '%,' + cast(r.rpt_id as varchar(255)) + ',%'
);
select rptName
from RptTable
where rpt_id in (
select CAST(LEFT(Reports, NULLIF(LEN(Reports)-1,-1)) AS INT) as Val
from repoAccess1
where uid = 'VIKRAM'
)
Your query would work fine when (LEFT(Reports, NULLIF(LEN(Reports)-1,-1)) ) returns either 1 or 2 since SQL Server implicitly converts the varchar value to numeric.
It seems there might be a data issue. One of the data returned by LEFT function is non-numeric. In order to find that particular record you can use isnumeric function. Try like this,
SELECT rptName
FROM RptTable
WHERE rpt_id IN (
SELECT LEFT(Reports, NULLIF(LEN(Reports) - 1, - 1))
FROM repoAccess1
WHERE uid = 'VIKRAM'
AND ISNUMERIC(LEFT(Reports, NULLIF(LEN(Reports) - 1, - 1))) = 1
)

SQL select max value of varchar

I have a varchar column that contains data like '0 03-03-14', '1 04-03-14' and so on.
I need to select the maximum one, in that case '1 04-03-14'.
My problem is that I can have the '1' (the max value) but how do I have to do if I also want the date ?
For now, I have this :
SELECT MAX(TO_NUMBER(SUBSTR(revision, 1, INSTR(revision, ' ')-1)))
FROM table
WHERE name = 'aname'
AND t_name = 'tname'
GROUP BY revision
Does anyone have an idea ?
Thanks
I assume you want something like max(version, date version), try this:
Select * from (
Select * from (
SELECT
TO_NUMBER(SUBSTR(revision, 1, INSTR(revision, ' ')-1)) as rev
, TO_DATE(SUBSTR(revision, 1, INSTR(revision, ' ')+1),'DD-MM-YY') as revDate
FROM table
WHERE name = 'aname'
AND t_name = 'tname'
) extracted
order by extracted.revDate, extracted.rev desc
) where rownum = 1
Do you mean this?
select max(revision)
from table
where name = 'aname' and t_name = 'tname';
It seems strange to put the revision number and date in one column. Is that really your data format? If not, modify your question with the actual data format.
Regarding your answers, I think the best solution would be to split those two parts :)

Conversion failed when converting the varchar value 'ADMIN' to data type int

I have sql like below. Home hints:
Results in K table (from WITH) gives number codes of specified range (ex.: 1-90).
The main select part works fine until I use
sum(F._IsInIntersection) [CountIntersection]
It causes error
Msg 245, Level 16, State 1, Line 11
Conversion failed when converting the varchar value 'ADMIN' to data type int.
If I comment this line, it is OK.
I do not know, why this error occurs the line with SUM() contains only int values. No ADMIN value (as mentioned in the error) exists anywhere...
Can anyone see any problems with the query?
;with K as (
select cast(c.Code as int) code
from rmCategory c, rmCategoryGroup cg, rmIdentification ic
where 1=1
and c.CategoryGroupID=cg.ID
and c.ID=ic.ID0
)
select
F.STAV_AKT [Code]
, count(F.STAV_AKT) [Count]
, sum(F._IsInIntersection) [CountIntersection]
from
(
select
f.*
, case when f.KVALIF IN (select code from K) and f.KVALIF is not null then 1 else 0 end _IsInIntersection
from frmFormData_208629_MaMo2_IMPORT f, rmIdentification i
where 1=1
and f.ID=i.id0
and i.isValid=1
and f.sysDAVKA=5
) F
group by F.STAV_AKT
order by F.STAV_AKT
I also tried CASTing parameter inside of sum(cast(F._IsInIntersection as int)) [CountIntersection] to be sure to use int values instead of the boolean ones, but no change.
Martin, I'm suspecting that c.Code also contains the value 'ADMIN' in the part
cast(c.Code as int) code
It runs good without the SUM because it's part of a CTE and is not materialized when the column is not used.
If for example I run the following code example in Fiddle it runs fine, but if I also select the column Code it fails when trying to CAST 'ADMIN' to INT (Fiddle).
;WITH cte as
(
select CAST(a AS INT) AS Code
,'Dummy' AS Column2
FROM (
SELECT 1 AS a
UNION ALL SELECT 'a'
) t
)
SELECT Column2
--,Code
FROM cte
So try to figure out what exactly the values for column Code are by using e.g.
SELECT DISTINCT Code FROM rmCategory
What is the datatype of f.sysDAVKA?
Try running
SELECT f.sysDAVKA
FROM frmFormData_208629_MaMo2_IMPORT f
WHERE f.sysDAVKA = 'ADMIN'
My gut feeling is you will find at least one row. If this is true, then changing your WHERE clause to
where 1=1
and f.ID=i.id0
and i.isValid=1
and f.sysDAVKA=CAST(5 AS char(1))
should resolve the problem.

Sorting SQL string by first 2 or 3 characters

I have been asked to sort a locations table in ascending order. The data in the table currently looks something like this:
100F01
105B02
10B01
GK1-A01
201E12
20A01
However, when this data is displayed on the screen I want it to sort the numeric results in ascending order and then the string results in alphabetic order. The output should look something like this:
10B01
20A01
100F01
105B02
201E12
GK1-A01
I have tried using the following code
SELECT location FROM freelocations
ORDER BY CAST(SUBSTRING(location, 1, 2) AS INT)
however, as expected, this returns an error message because some locations don't start with a numeric:
Conversion failed when converting the varchar value 'GK' to data type int.
Any ideas or tips will be greatly appreciated
Maybe something like this?
select location
from freelocations
order by
case
when patindex('%[^0-9]%', location) = 1 then 9999999999
else cast(substring(location, 1, patindex('%[^0-9]%', location) - 1) as int)
end,
location
(It's a bit clumsy due to SQL Server lacking a regex replace function)
order by FIELD(string+0,1),string+0
but note that '10e20' will be misinterpreted!
Before casting you should check if the first 2 or 3 characters really are digits:
SELECT
location
FROM
freelocations
ORDER BY
CASE
WHEN location like '[0-9][0-9][0-9]%' THEN cast(substring(location,1,3) AS INT)
WHEN location like '[0-9][0-9]%' THEN cast(substring(location,1,2) AS INT)
ELSE 9999
END
Try this to avoid casting:
SELECT
x,
RIGHT('000' +LEFT (x,patindex('%[^0-9]%',x)-1),3) sort1,
RIGHT (x,LEN(x)-patindex('%[^0-9]%',x)+1) sort2
FROM
(
SELECT '123asdf' x
UNION
SELECT '12asdf'
UNION
SELECT '13asdf'
UNION
SELECT '12zsdf'
) X
ORDER BY sort1 ,sort2