how to convert the output of sub query into numeric - sql

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
)

Related

Error while converting varchar to Decimal

In my table I have a column(Varchar). It contains values like 'abc^1234567^xyz'.
I need to select part of the value and convert it to select the number and convert it to a decimal number and compare this number to a number from another table by joining two tables.
So far I get error while want to convert it from varchar to decimal.
Here is my error message:
Msg 8114, Level 16, State 5, Line 1
Error converting data type varchar to numeric.
Here is my code:
SELECT
a.Status,
Cast(SUBSTRING(sourceNatKey, LEN(sourceNatKey)-11,7) As Decimal(18,4)),
b.caseId
FROM AGREEMENT_STATUS a
INNER JOIN APPLICATION_FACT b
ON
Cast(SUBSTRING(sourceNatKey, LEN(sourceNatKey)-11,7) As decimal(18,4)) =
b.caseId
You could use the LIKE operator in the JOIN for such situations.
But if you really have to get a substring from such string ('abc^1234567^xyz'), you could use such construction:
SELECT
a.Status,
Cast(SUBSTRING(sourceNatKey, CHARINDEX('^',sourceNatKey) + 1,CHARINDEX('^',sourceNatKey, CHARINDEX('^',sourceNatKey)+1) - CHARINDEX('^',sourceNatKey) - 1) As decimal(18,4)),
b.caseId
FROM AGREEMENT_STATUS a
INNER JOIN APPLICATION_FACT b
ON
Cast(SUBSTRING(sourceNatKey, CHARINDEX('^',sourceNatKey) + 1,CHARINDEX('^',sourceNatKey, CHARINDEX('^',sourceNatKey)+1) - CHARINDEX('^',sourceNatKey) - 1) As decimal(18,4)) =
b.caseID
You could do this the other way:
SELECT
a.Status,
b.caseId
FROM AGREEMENT_STATUS a JOIN
APPLICATION_FACT af
ON sourceNatKey LIKE '%^' + CAST(b.caseID as varchar(255)) + '^%'
The caseId column has the information in your second column, so that doesn't need to be repeated.
The code SUBSTRING(sourceNatKey, LEN(sourceNatKey)-11,7) will result in ^123456 given the value abc^1234567^xyz. This fails because ^ is non-numeric. Change the offset value from the LEN call to be -10 in order to only retrieve the numeric part of your string.
For further information regarding SUBSTRING, see SUBSTRING (Transact-SQL) Documentation.

How to use INTO and GROUP BY clause together

SELECT cast ( SUBSTRING ( CAST ("ProcessingDate" AS text), 5, 2 ) as integer),
COUNT(*) INTO resultValue1,resultValue2
FROM "DemoLogs"."Project"
WHERE "Addr" = 'Y' AND "ProcessingDate" >= 20160110
GROUP BY 1
ORDER BY 1;
In my database, the ProcessingDate is stored as YYYYMMDD. So, I am extracting its month from it.
This query is working fine if we remove the INTO clause but, I want to store the result to use it further.
So what should be the datatype of the variable resultValue1 and resultValue2 how to store the data(because data will be multiple).
As I am new to PostgreSQL I don't know how to do this can anybody help me out.
Here resultValue1 & resultValue2 will be tables not variables. you can group by using the column names.
Give some column alias names for both columns and group by using them.
You probably want this.
SELECT cast ( SUBSTRING ( cast ("ProcessingDate" as text),5 , 2 ) as
integer) AS resultValue1, COUNT(*) AS resultValue2
INTO <NewTable> --NewTable will be created with those two columns
FROM "DemoLogs"."Project"
-- conditions
Group By 1
-- other contitions/clauses
;
Kindly refer this INTO Documentation.
Hope this helps.
Try this:
SELECT cast ( SUBSTRING ( cast ("ProcessingDate" as text),5 , 2 ) as integer)resultValue1,
COUNT(*)resultValue2
INTO <Table Name>
FROM "DemoLogs"."Project"
WHERE "Addr" = 'Y'
AND "ProcessingDate" >= '20160110'
Group By 1
Order By 1;
Store the above query in the variable and remove that INTO clause from it.
So, query will be now :
query = SELECT cast ( SUBSTRING ( CAST ("ProcessingDate" AS text), 5, 2 ) as
integer),
COUNT(*)
FROM "DemoLogs"."Project"
WHERE "Addr" = 'Y' AND "ProcessingDate" >= 20160110
GROUP BY 1
ORDER BY 1;
Now declare result_data of type record and use in the following manner:
We are looping over result_data because it gives number of rows as output
and I have declared resultset of type text to store the result (as I needed further)
FOR result_data IN EXECUTE query
LOOP
RAISE NOTICE 'result : %',to_json(result_data);
resultset = resultset || to_json(result_data);
END LOOP;

SQL Query Remove Part of Path/Null

So I am new the whole SQL Query business but I need some help with two issues. My goal is to have anything in the Column "EnvironmentName" that has the word "Database" in Column "NodeName" to be displayed in the query results. I did this with
FROM [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con]
WHERE NodeName = 'Database'
ORDER BY EnvironmentName asc
WHERE NodePath
Results of Query:
I am able to get my query results but would like to remove the rows with NULL. I have tried to use "IS NOT NULL" but SQL Server Management Studio labeles this as "incorrect syntax."
What I have tried:
FROM [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con]
WHERE NodeName = 'Database'
ORDER BY EnvironmentName asc IS NOT NULL
WHERE NodePath
Thank you in advance!
Your query is pretty close..
1: You have to specify a specific column to not be null while using IS NOT NULL.
So modify your query to:
FROM [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con]
WHERE NodeName = 'Database' AND EnvironmentName IS NOT NULL
ORDER BY EnvironmentName asc
WHERE NodePath
2: Check out this article about trimming parts of strings from query results
http://basitaalishan.com/2014/02/23/removing-part-of-string-before-and-after-specific-character-using-transact-sql-string-functions/
Where clause will come first and Then order by statement
Like following way
Select * FROM [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con]
WHERE [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con].[NodeName] = 'Database' AND [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con].[EnvironmentName] IS NOT NULL
ORDER BY [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con].[EnvironmentName] asc
EDIT: I just noticed you removed this from your OP, so feel free to disregard if you took care of that.
I don't think anyone addressed the substring problem yet. There's several ways you could get at this depending on how complex the strings are you have to slice up, but here's how I'd do it
-- Populating some fake data, representative of what you've got
if object_id('tempdb.dbo.#t') is not null drop table #t
create table #t
(
nPath varchar(1000)
)
insert into #t
select '/Database/Mappings/Silver/Birthday' union all
select '/Database/Connections/Blue/Happy'
-- First, get the character index of the first '/' after as many characters the word '/database/' takes up.
-- You could have hard coded this value too. Add 1 to it so that it moves PAST the slash.
;with a as
(
select
ixs = charindex('/', nPath, len('/Database/') + 1),
-- Get everything to the right of what you just determined with all the charindex() stuff
ss = right(nPath, len(nPath) - charindex('/', nPath, len('/Database/') + 1)),
nPath
from #t
)
-- Now just take the left of the now-cleaned-up string from start to the first pipe
select
ixs,
ss,
color = left(ss, charindex('/', ss) -1),
nPath
from a

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