Return non-numeric characters - sql-server

I have 1 table.
Result
I want to show columns Names and Digits.
How do I return all rows that has a non-numeric characters in the Digits.
Thanks.

You can use ISNUMERIC function
ISNUMERIC returns 1 when the input expression evaluates to a valid numeric data type; otherwise it returns 0.
SELECT names, digit
FROM yourTable
WHERE ISNUMERIC(digit) = 0

You could use PATINDEX
Declare #SampleData as Table
(
Id int,
Digit varchar(10)
)
insert into #SampleData
values
( 1, '100'),(2,'2ab'),
(3,'200'), (4, ''), (5, 'a11')
select * from #SampleData
where PATINDEX('%[^0-9]%',Digit) > 0
Returns
Id Digit
----------
2 2ab
5 a11

Related

Compare two different column in sql server to get result

i'm stuck in problem, i want to get result who's value falls between SlabFrom & Slabto
Query:
Declare #Userinputvalue Decimal(11,6);
Set #Userinputvalue = '700001';
select * from _TaxRate
where SlabTo >= #Userinputvalue and SlabFrom <= #Userinputvalue
TABLE DATA (EXISTING DATA)
SRNO SlabFrom SlabTo Perage
-----------------------------------------
1 0 600000 0
2 600001 1200000 5
3 1200001 1500000 7
4 1500001 2000000 10
Above Result
No Data Found / Blank
But, I Need suppose row number two because my user input value found between (600001 - 1200000), but above query return no data.
Any Help will be highly appreciated.
If you run this code you'll see why
Declare #Userinputvalue Decimal(11,6);
Set #Userinputvalue = '700001';
select #Userinputvalue;
The result is arithmetic overflow. Decimal(11, 6) is not wide enough to store '700001'
Suppose all of the columns are integers, then it works without issues
Data
drop table if exists #tTest;
go
create table #tTest(
SRNO int,
SlabFrom int,
SlabTo int,
Perage int);
insert #tTest(SRNO, SlabFrom, SlabTo, Perage) values
(1, 0, 600000, 0),
(2, 600001, 1200000, 0),
(3, 1200001, 1500000, 0),
(4, 1500001, 2000000, 0);
Query
Declare #Userinputvalue int;
Set #Userinputvalue = 700001;
select *
from #tTest t
where SlabTo >= #Userinputvalue
and SlabFrom <= #Userinputvalue;
Output
SRNO SlabFrom SlabTo Perage
2 600001 1200000 0

Accessing prior rows and divide its value by current row

I have the rows below, and i want to access prior row and divide its value by current row. For every row, i need to calculate the Vi value, this Vi value is equal to Vi-1/Vi which means that:
Given the table
Table T
id value out
1 100
2 200
3 10
4 50
I want to generate these values
V1 = 100
V2= 100/200 = 0.5
V3 = 0.5/10 = 0.05
V4 = 0.05/50 = 0.001
So at the end i want the following output:
id value out
1 100 100
2 200 0.5
3 10 0.05
4 50 0.001
I tried using the aggregate function SUM with OVER(), but i do not know how to solve this problem as i need to divide and not sum the value
SELECT id, value, SUM(value) OVER(ORDER BY id ROWS BETWEEN
1 PRECEDING AND 1 PRECEDING ) / value as out
FROM T
Sample data:
CREATE TABLE t(
id INT,
value INT
);
INSERT INTO t VALUES
(1, 100), (2, 200), (3, 10), (4, 50);
Unfortunately, SQL do not have Product, but it should be simple to use cte. The performance should be not bad if id was indexed
DECLARE #T table (id int identity(1,1) primary key, value int)
INSERT #T VALUES (100), (200), (10), (50)
;WITH cte AS
(
SELECT id, value, CAST(value AS decimal(20,4)) AS out FROM #T WHERE id = 1
UNION ALL SELECT T.id, T.value, CAST(cte.out / T.value AS decimal(20,4)) FROM cte INNER JOIN #T T ON cte.id = T.id - 1
)
SELECT * FROM cte

SQL Server: How to write a query to select id having all values less than 0(zero)

Consider the following table,
Table 1:
id (int): 1 1 2 2 2
value (int): -1 0 -1 -3 -8
How to write a query to select the id from the table which has all the values of column value less than 0?
Try this one -
DECLARE #temp TABLE
(
id INT,
value INT
)
INSERT INTO #temp (id, value)
VALUES (1, -1), (1, 0), (2, -1), (2, -3), (2, -8)
SELECT id
FROM #temp
GROUP BY id
HAVING MAX(value) < 0
Output -
id
-----------
2

How to check whether (var)char is a valid ISO date (112)

I have a char(8) field which should really contain a value in a yyyymmdd dateformat.
Given a (hypothetical) table id(int)|datestring(char(8)) I would like to be able to do something like
SELECT id, isValidDate(datestring) FROM my_hypothetical_table
It's important for me that this can be run like so as a query (so I could, for example, SELECT * from othertable INNER JOIN hypothetical_table on hypothetical_table.id = othertable.hypothetical_FK WHERE isValidDate(hypothetical_table.datestring) = 1). Catching errors doesn't seem viable.
Note that the IsDate() function only works with slash delimited dates, and not yyyymmdd formats.
You may want to add a check for length if you are unsure about all values being 8 digits in length.
DECLARE #MyTable TABLE (id INT, datestring CHAR(8))
INSERT INTO #MyTable VALUES (1, '20110711')
INSERT INTO #MyTable VALUES (2, '2011')
INSERT INTO #MyTable VALUES (3, '20110228')
INSERT INTO #MyTable VALUES (4, '20110229')
INSERT INTO #MyTable VALUES (5, '2011071')
INSERT INTO #MyTable VALUES (6, '201107')
SELECT id, datestring, ISDATE(datestring) AS IsDate FROM #MyTable
Running this produces the output:
id datestring IsDate
----------- ---------- -----------
1 20110711 1
2 2011 1
3 20110228 1
4 20110229 0
5 2011071 0
6 201107 1
ISDATE() will work with YYYYMMDD format too
SELECT ISDATE('20010101')

Extract multiple numeric values from string with T-SQL

I have a column with data in a special “format”. Example:
L100000
L50
L5
S10
S15L10
S20
S90
S10
S10L5
S10L40
S10L5
The value consists of an “S” and/or an “L”, each with a number following the letter.
I need to write a query, which will return two columns, “S” and “L”, which will have only the coresponding numeric value following the letter.
The above example should look like this:
S L
======== ==========
0 100000
0 50
0 5
10 0
15 10
20 0
90 0
10 0
10 5
10 40
10 5
If no "S" or "L" is found, the default value is zero.
try this:
DECLARE #YourTable table (RowValue varchar(30))
INSERT INTO #YourTable VALUES ('L100000')
INSERT INTO #YourTable VALUES ('L50')
INSERT INTO #YourTable VALUES ('L5')
INSERT INTO #YourTable VALUES ('S10')
INSERT INTO #YourTable VALUES ('S15L10')
INSERT INTO #YourTable VALUES ('S20')
INSERT INTO #YourTable VALUES ('S90')
INSERT INTO #YourTable VALUES ('S10')
INSERT INTO #YourTable VALUES ('S10L5')
INSERT INTO #YourTable VALUES ('S10L40')
INSERT INTO #YourTable VALUES ('S10L5')
SELECT
CASE
WHEN LocationS>0 AND LocationL=0 THEN RIGHT(RowValue,Length-1)
WHEN LocationS>0 THEN SUBSTRING(RowValue,2,LocationL-2)
ELSE NULL
END AS S
,CASE
WHEN LocationS=0 AND LocationL>0 THEN RIGHT(RowValue,Length-1)
WHEN LocationS>0 AND LocationL>0 THEN RIGHT(RowValue,Length-LocationL)
ELSE NULL
END AS L
,RowValue
FROM (SELECT
RowValue
,CHARINDEX('S',RowValue) AS LocationS
,CHARINDEX('L',RowValue) AS LocationL
,LEN(RowValue) AS Length
FROM #YourTable
) dt
OUTPUT
S L RowValue
------------------------------ ------------------------------ --------------
NULL 100000 L100000
NULL 50 L50
NULL 5 L5
10 NULL S10
15 10 S15L10
20 NULL S20
90 NULL S90
10 NULL S10
10 5 S10L5
10 40 S10L40
10 5 S10L5
(11 row(s) affected)
if you have loads of data give this a try, it may be faster (has same output, basically removed the derived table and made everything use inline functions):
SELECT
CASE
WHEN CHARINDEX('S',RowValue)>0 AND CHARINDEX('L',RowValue)=0 THEN RIGHT(RowValue,LEN(RowValue)-1)
WHEN CHARINDEX('S',RowValue)>0 THEN SUBSTRING(RowValue,2,CHARINDEX('L',RowValue)-2)
ELSE NULL
END AS S
,CASE
WHEN CHARINDEX('S',RowValue)=0 AND CHARINDEX('L',RowValue)>0 THEN RIGHT(RowValue,LEN(RowValue)-1)
WHEN CHARINDEX('S',RowValue)>0 AND CHARINDEX('L',RowValue)>0 THEN RIGHT(RowValue,LEN(RowValue)-CHARINDEX('L',RowValue))
ELSE NULL
END AS L
,RowValue
FROM #YourTable
SELECT
SVal = CASE
WHEN PATINDEX('S%L%', TextVal) > 0 THEN REPLACE(LEFT(TextVal, CHARINDEX('L', TextVal) - 1), 'S', '')
WHEN PATINDEX('S%', TextVal) > 0 THEN REPLACE(TextVal, 'S', '')
ELSE '0'
END,
LVal = CASE
WHEN PATINDEX('S%L%', TextVal) > 0 THEN REPLACE(RIGHT(TextVal, LEN(TextVal) - CHARINDEX('L', TextVal)), 'L', '')
WHEN PATINDEX('L%', TextVal) > 0 THEN REPLACE(TextVal, 'L', '')
ELSE '0'
END
FROM StringList
Assumes S always comes before L. Also you might want to cast the results as numbers (they are strings now) depending on what you need for the output.
I would suggest a clr-based function which would use a regex to extract the S or L value from the string. You could use it like this:
insert new_table (s_value, l_value)
select getValue('S', original_value), getValue('L', original_value)
from original_table
not tested but should be close assuming s always appears before l:
select
case when charindex(data, 's') <> 0 then
substr(data, charindex(data, 's'), charindex(data ,'l'))
else 0 end
, case when charindex(data, 'l') <> 0 then
substr(data, charindex(data, 'l'))
else 0 end
from some_table

Resources