Define where condition between specified interval in SQL? - sql

I want select between 1700300000 to 1700500000 also type of MemberID is nvarchar(50)
select * from tblmember
where cast(MenmberID as bigint) > 1700300000 and cast(MemberID as bigint) < 1700500000
error: Msg 8114, Level 16, State 5, Line 25
Error converting data type nvarchar to bigint.

Use try_cast():
select *
from tblmember
where try_cast(MemberID as bigint) > 1700300000 and
try_cast(MemberID as bigint) < 1700500000
I don't know what your data looks like, but you might be able to use string comparisons:
select *
from tblmember
where MemberID > '1700300000' and
MemberID < '1700500000'

Your problem is that you have non-numerical data in the table.
If the data is non-numerical, it fails the conversion.
In addition to Gordon's fine answers, you could try the following:
select * from tblmember
where
(case when isnumeric(MemberID) = 1 then cast(MemberID as bigint) end) > 1700300000 and
(case when isnumeric(MemberID) = 1 then cast(MemberID as bigint) end) < 1700500000
;

select * from tblmember
where case when isNumeric(MemberID) then cast(MenmberID as bigint)
else 0 end between 1700300000 and 1700500000;
something like that? (if you want/don't want the edge cases then you can play with the between -1/+1 on the values). What about 1700524234.3? Is that ok with you or does it have to be an integer?

Related

Conditionally modify query based on parameter

I have this query (something like a case statement which I can use and fix it)
select *
from mytable
where 1=1
and (isNull(ID, 0) = 0 OR UtilityID IN (9,40))
I also want to add another statement
select *
from mytable
where 1=1
and UtilityID NOT IN (9,40)
Everything is happening in a procedure, so want to use a variable like declare #something so if that is passed as 1, use the first statement and the if 0 is passed, use the latter one.
While I appreciate the genius in Dale's answer I find this more readable:
IF #something = 0
BEGIN
select *
from mytable
where ID IS NULL OR ID = 0 OR UtilityID IN (9,40);
END
IF #something = 1
BEGIN
select *
from mytable
where UtilityID NOT IN (9,40);
END
It's procedure code, so use IF to direct the control flow. Also expanded and simplified your where clauses
I think I understand your logic, ignoring the 1=1 (which does nothing) you want to only allow id = 0 when #something = 1. This should do it:
declare #something bit = 0;
declare #mytable table (ID int, UtilityID int);
insert into #mytable (ID, UtilityID)
select 0, 1 union all
select 1, 2 union all
select 2, 9 union all
select 3, 40;
select *
from #mytable
where (
(#something = 1 and (isnull(ID, 0) = 0 or UtilityID in (9,40)))
or (#something = 0 and (UtilityID not in (9,40)))
);
A more performant approach for a larger query could be:
select *
from #mytable
where (#something = 1 and (isnull(ID, 0) = 0 or UtilityID in (9,40)))
union all
select *
from #mytable
where (#something = 0 and (UtilityID not in (9,40)));
PS: Hopefully your ID cannot ever by null - it should have a constraint on it.

Converting varchar to int (a strange case?)

I have scoured through all "Varchar to Int" posts but can't seem to find anyone with this issue (although, I am fairly new to SQL so I may be doing something fundamentally wrong):
SELECT *
FROM [TABLE]
WHERE CONVERT(INT,
CASE
WHEN NOT CONVERT(VARCHAR(12), dept_code) LIKE '%[^0-9]%' THEN 8900
END) < 9000;
It's a fairly simple query, where the goal is to filter out all the values in field "dept_code" so that only fully numeric values less than 9000 are kept; varchars and non-numeric values are fine to stay. When running the above I still get the error "Conversion failed when converting the varchar value 'E103' to data type int."
Any help would be appreciated.
You can simply this query by avoiding CASE and Regex like expression. You can use IsNumeric function to filter numeric rows and then apply the condition by converting dept_code of filtered rows to int, like below -
select * from tablex
where ISNUMERIC(dept_code) = 0 --alphanumeric code
OR(ISNUMERIC(dept_code) = 1 and Convert(int, dept_code) < 9000) -- numeric less than 9000
Example here
Use try_convert() or try_cast():
SELECT t.*
FROM [TABLE] t
WHERE TRY_CONVERT(int, dept_code) < 9000
If you want to speed this query, you can materialize a computed column and add an index:
alter table [table] add dept_code_int as (try_convert(int, dept_code)) persisted;
create index idx_table_dept_code_int on [table](dept_code_int);
You are missing an else in your case statement ... Secondly do your numeric dept_codes get to be really big ... this thing will choke on that.
SELECT *
FROM [TABLE]
WHERE CONVERT(INT,
CASE
WHEN NOT CONVERT(VARCHAR(12), dept_code) LIKE '%[^0-9]%' THEN 8900 ELSE dept_code
END) < 9000;
Try this: http://sqlfiddle.com/#!18/bb6b7/17
;WITH TABLE_ENHANCED AS
(
SELECT
t.*
, dept_code_numeric =
CASE
WHEN CONVERT(VARCHAR(12), dept_code) NOT LIKE '%[^0-9]%'
THEN CONVERT(INT, dept_code)
ELSE 0
END
FROM [TABLE] t
)
SELECT
*
FROM TABLE_ENHANCED
WHERE dept_code_numeric < 9000
Try below Script
SELECT *
FROM [TABLE]
WHERE isnumeric(dept_code)=1
and dept_code<9000;
This should work. The conversion to int is implicit.
SELECT *
FROM test
WHERE (ISNUMERIC(dept_code)=1 and dept_code<9000)
or (ISNUMERIC(dept_code) = 0)

if statement in sql server

i am getting the following error:
Incorrect syntax near 'cast', expected 'AS'.
on this line:
use SalesDWH
go
if (select isnumeric(result))=1
begin
select max(cast(result) as decimal(10,2)) from testresults
end
testresults table contains about 21 million rows of data.
what am i doing wrong? thanks so much.
thank you everyone for you rhelp.
i've changed the code to:
use SalesDWH
go
if (select isnumeric(result))=1
begin
select max(cast(result as decimal(10,2))) from testresults
end
and now i am getting error:
Msg 207, Level 16, State 1, Line 1
Invalid column name 'result'.
it's definitely a valid column
i took kris' suggestion and did this:
use SalesDWH
go
SELECT MAX( CAST( [Result] AS DECIMAL(9,2) ) )
FROM [testresults]
WHERE ISNUMERIC( [Result] ) = 1
and dbo.isReallyNumeric([Result]) = 1
and dbo.isReallyInteger([Result]) = 1
the functions are here http://classicasp.aspfaq.com/general/what-is-wrong-with-isnumeric.html
and the result that i got was NULL!!!!!
i need a numeric result. what am i doing wrong?
here is a sample of the data:
625857 AMPH-AMPHETAMINES 357.1 EBB74CF9-D12D-4FBC-917F-91D9DAC169F3
625858 AMP_C-Amphetamine NEGATIVE EBB74CF9-D12D-4FBC-917F-91D9DAC169F3
625859 BARB-BARBITURATES 7.1 EBB74CF9-D12D-4FBC-917F-91D9DAC169F3
625860 BENZ-BENZODIAZEPINES 1.2 EBB74CF9-D12D-4FBC-917F-91D9DAC169F3
625861 COCN-COCAINE METABOLITES -105.5 EBB74CF9-D12D-4FBC-917F-91D9DAC169F3
625862 CR-CREATININE (CHEMICAL) 57.8 EBB74CF9-D12D-4FBC-917F-91D9DAC169F3
625863 ETOH-ETHANOL 134.5 EBB74CF9-D12D-4FBC-917F-91D9DAC169F3
625864 METAMP_C-Methamphetamine NEGATIVE EBB74CF9-D12D-4FBC-917F-91D9DAC169F3
625865 METD-METHADONE -32.3 EBB74CF9-D12D-4FBC-917F-91D9DAC169F3
thank you for all your help. i think i am getting closer:
select MAX(cast(char_value as decimal(10,2))) from
(SELECT
Char_Number = CASE
WHEN id <= 255 THEN RTRIM(id)
ELSE '-' END,
Char_Value = RTRIM(CASE
WHEN id <= 255 THEN CHAR(id)
ELSE result END),
is_numeric = ISNUMERIC(result),
is_really_numeric = dbo.isReallyNumeric(result),
is_really_integer = dbo.isReallyInteger(result)
FROM
testresults
WHERE
ISNUMERIC(result) = 1
OR dbo.isReallyNumeric(result) = 1
OR dbo.isReallyInteger(result) = 1
)
where is_really_numeric=1
but i am getting this error:
Msg 156, Level 15, State 1, Line 20
Incorrect syntax near the keyword 'where'.
updated based on guess of what you were looking for
SELECT MAX( CAST( [Result] AS DECIMAL(10,2) ) )
FROM [testresults]
WHERE ISNUMERIC( [Result] ) = 1;
Try this one
use SalesDWH
go
SELECT MAX(CAST(Result AS DECIMAL(10,2))) FROM testresults WHERE isnumeric(result)=1
But if you get NULL as a result even with this:
and dbo.isReallyNumeric([Result]) = 1
and dbo.isReallyInteger([Result]) = 1
then this may be the actual result - there is no any numberic values in the column
OR
the really numberic values of column are left- or right-padded with spaces etc...
OR
you stripe all the floats with this dbo.isReallyInteger([Result]) = 1 and you have no pure integers in the table
If you are still getting the error, just give an alias to your inner table.
select MAX(cast(char_value as decimal(10,2))) from
(SELECT
Char_Number = CASE
WHEN id <= 255 THEN RTRIM(id)
ELSE '-' END,
Char_Value = RTRIM(CASE
WHEN id <= 255 THEN CHAR(id)
ELSE result END),
is_numeric = ISNUMERIC(result),
is_really_numeric = dbo.isReallyNumeric(result),
is_really_integer = dbo.isReallyInteger(result)
FROM
testresults
WHERE
ISNUMERIC(result) = 1
OR dbo.isReallyNumeric(result) = 1
OR dbo.isReallyInteger(result) = 1
) myInnerTable
where is_really_numeric=1

SQL: How use case and cast in a query?

I want to cast VARCHAR to INT, but in my table i have some value like '???' then SQL Server launch this expcetion :
Conversion failed when converting the varchar value '????' to data type int.
Severity 16
I could convert this '???' to NULL, that's no problem, but how do that ?
I'm trying to do something like this:
INSERT INTO labbd11..movie(title, year)
SELECT movies.title,
CASE movies.mvyear IS '????' THEN NULL ELSE CAST (movies.mvyear AS INT)
FROM disciplinabd..movies
But nothing works ..
Any ideas guys ?
You might just want to solve this in general and deal with any non-int value the same way
INSERT INTO labbd11..movie(title, year)
SELECT movies.title,
CASE WHEN IsNumeric(movies.mvyear+ '.0e0') <> 1 THEN NULL
ELSE CAST (movies.mvyear AS INT) END
FROM disciplinabd..movies
See this question
I believe you would want something like
INSERT INTO labbd11..movie(title, year)
SELECT movies.title,
CAST( CASE movies.mvyear
WHEN '????' THEN NULL
ELSE movies.mvyear
END AS INT)
FROM disciplinabd..movies
You want your CASE statement to return a VARCHAR (either the MVYEAR or NULL) and then you want the CAST to operate on the result of the CASE.
INSERT INTO labbd11..movie(title, year)
SELECT movies.title,
CASE WHEN movies.mvyear = '????' THEN NULL
ELSE CAST (movies.mvyear AS INT) END
FROM disciplinabd..movies
INSERT INTO labbd11..movie(title, year)
SELECT
movies.title,
CAST(CASE WHEN movies.mvyear = '????' THEN NULL ELSE movies.mvyear END AS INT)
FROM
disciplinabd..movies
You can also use:
CAST(NULLIF(movies.mvyear,'????') AS INT)

is it possible to select EXISTS directly as a bit?

I was wondering if it's possible to do something like this (which doesn't work):
select cast( (exists(select * from theTable where theColumn like 'theValue%') as bit)
Seems like it should be doable, but lots of things that should work in SQL don't ;) I've seen workarounds for this (SELECT 1 where... Exists...) but it seems like I should be able to just cast the result of the exists function as a bit and be done with it.
No, you'll have to use a workaround.
If you must return a conditional bit 0/1 another way is to:
SELECT CAST(
CASE WHEN EXISTS(SELECT * FROM theTable where theColumn like 'theValue%') THEN 1
ELSE 0
END
AS BIT)
Or without the cast:
SELECT
CASE
WHEN EXISTS( SELECT 1 FROM theTable WHERE theColumn LIKE 'theValue%' )
THEN 1
ELSE 0
END
SELECT CAST(COUNT(*) AS bit) FROM MyTable WHERE theColumn like 'theValue%'
When you cast to bit
0 -> 0
everything else -> 1
And NULL -> NULL of course, but you can't get NULL with COUNT(*) without a GROUP BY
bit maps directly to boolean in .net datatypes, even if it isn't really...
This looks similar but gives no row (not zero) if no matches, so it's not the same
SELECT TOP 1 CAST(NumberKeyCOlumn AS bit) FROM MyTable WHERE theColumn like 'theValue%'
You can use IIF and CAST
SELECT CAST(IIF(EXISTS(SELECT * FROM theTable
where theColumn like 'theValue%'), 1, 0) AS BIT)
I'm a bit late on the uptake for this; just stumbled across the post. However here's a solution which is more efficient & neat than the selected answer, but should give the same functionality:
declare #t table (name nvarchar(16))
declare #b bit
insert #t select N'Simon Byorg' union select N'Roe Bott'
select #b = isnull((select top 1 1 from #t where name = N'Simon Byorg'),0)
select #b whenTrue
select #b = isnull((select top 1 1 from #t where name = N'Anne Droid'),0)
select #b whenFalse
You can also do the following:
SELECT DISTINCT 1
FROM theTable
WHERE theColumn LIKE 'theValue%'
If there are no values starting with 'theValue' this will return null (no records) rather than a bit 0 though
SELECT IIF(EXISTS(SELECT * FROM theTable WHERE theColumn LIKE 'theValue%'), 1, 0)
No it isn't possible. The bit data type is not a boolean data type. It is an integer data type that can be 0,1, or NULL.
Another solution is to use ISNULL in tandem with SELECT TOP 1 1:
SELECT ISNULL((SELECT TOP 1 1 FROM theTable where theColumn like 'theValue%'), 0)
I believe exists can only be used in a where clause, so you'll have to do a workaround (or a subquery with exists as the where clause). I don't know if that counts as a workaround.
What about this:
create table table1 (col1 int null)
go
select 'no items',CONVERT(bit, (select COUNT(*) from table1) ) -- returns 'no items', 0
go
insert into table1 (col1) values (1)
go
select '1 item',CONVERT(bit, (select COUNT(*) from table1) ) --returns '1 item', 1
go
insert into table1 (col1) values (2)
go
select '2 items',CONVERT(bit, (select COUNT(*) from table1) ) --returns '2 items', 1
go
insert into table1 (col1) values (3)
go
drop table table1
go