How to add Leading Zeros in Sequence in SQL Server 2012? - sql

I have a column in my Table i.e. TieBreaker which accepts only 4 digits Length value.
I have wrote a SQL SEQUENCE to generate a Series :
/* Snippet to DELETE Existing Sequence*/
IF EXISTS
(
SELECT * FROM Sys.Sequences WHERE Name = 'TieBreaker'
) DROP SEQUENCE TieBreaker
GO
/* Snippet to CREATE Sequence*/
CREATE SEQUENCE TieBreaker AS INT
START WITH 0000
INCREMENT BY 1
MINVALUE 0000
MAXVALUE 9999
CYCLE
GO
How can I output with Leading 0 for my sequence ? Like Below :

You do not. A number has no leading zeroes, as we all have learned in school.
The character formatting has. So you have 3 choices:
Make the field a varchar. This is not totally off as many number sequences also have prefixes and ARE NOT NUMBERS.
Add another computed field that formats the output so you can use that.
Do not care on database level but format in whatever program uses it.

An example of using a computed column for formatting
CREATE TABLE Test (
TieBreakerSeq INT DEFAULT NEXT VALUE FOR TieBreaker,
TieBreakerAsChar AS FORMAT(TieBreakerSeq, '0000#'),
SomeOtherData VARCHAR(10)
)
INSERT INTO Test (SomeOtherData) VALUES ('A'),('B'),('C')
SELECT * FROM Test
TieBreakerSeq TieBreakerAsChar SomeOtherData
------------- ---------------- -------------
0 00000 A
1 00001 B
2 00002 C

did u try
select lpad(TieBreaker.nextval,'4','0') from dual;
it would give same result right?
0000
0001
0002 and so on..

Related

How can I find only one distinct digit in a cell in SQL

I have customer data with mobile phone numbers where '1' has been entered 10 times or more in a cell to bypass the customer onboarding system validation. For example '1111111111'
I used below condition in my where clause but that didn't really help.
AND p.mobile_no LIKE '%[1111111111]%'
It is possible that users might enter 1 multiple number of times in the new customer form to bypass validation. To find only 0 values in the cell I used %[^0]% in the WHERE clause and I was hoping to use something similar to find 1s where regardless of how many times it has been entered in the field, as long as it only has 1 in it it will skim out the data for me.
How can I find these instances in my data using a SQL query?
The goal is to find these anomalies and remove them.
Using: Microsoft SQL Server 2016 (SP2).
I think you are looking for the following, which tests if at least 1 '1' exists, and that no other characters exist.
select Number
from (values ('111'),('121'),('1-2'),('22')) x (Number)
-- Test that at least 1 '1' exists
where Number like '%1%'
-- And that no other allowable characters exist - expand to cover all options
and Number not like '%[0,2-9,-]%'
Using a table to define invalid phone numbers:
Declare #invalidPhoneNumbers Table (PhoneNumber char(10));
Insert Into #testData (PhoneNumber)
Values ('0000000000'), ('1111111111'), ('2222222222'), ('3333333333'), ('4444444444')
, ('5555555555'), ('6666666666'), ('7777777777'), ('8888888888'), ('9999999999');
Select ...
From ...
Where ...
And p.mobile_no Not In (Select i.PhoneNumber From #invalidPhoneNumbers i)
Or - using NOT EXISTS which may perform better:
Declare #invalidPhoneNumbers Table (PhoneNumber char(10));
Insert Into #testData (PhoneNumber)
Values ('0000000000'), ('1111111111'), ('2222222222'), ('3333333333'), ('4444444444')
, ('5555555555'), ('6666666666'), ('7777777777'), ('8888888888'), ('9999999999');
Select ...
From ...
Where ...
And Not Exists (Select * From #invalidPhoneNumbers i Where i.PhoneNumber = p.mobile_no)
When declaring the table - make sure the data type defined matches exactly the defined data type of p.mobile_no. This will make sure there are no implicit conversions that can cause issues.

Query to find if a column contains both number and decimal only

I have a column to check if contains number from 0-9 and a decimal. Since in the version of SQL am using the below does not seem working
select *
from tablename
whwere columnname like '%[^.0-9]%'
Also tried using column name like '%[0-9]%' and columnname not like '%.%' but if there is a negative sign it is not getting captured. Please advise.
The column data type is float. So can someone provide me a query to check if the column contains values from 0-9 and also it can contain decimal values these two are permitted. If say for example if I have value 9,9.99 ,-1.24 the query should output -1.24 I need this value other than decimal and number –
The issue with your LIKE clause is bad predicate logic ...like '%[^.0-9]%'should be NOT LIKE '%[^0-9.]%'
Take this sample data.
DECLARE #table TABLE (SomeNbr VARCHAR(32));
INSERT #table VALUES ('x'),('0'),('0.12'),('999'),('-29.33'),('88.33.22'),('9-9-'),('11-');
What you were trying to do would be accomplished like this:
SELECT t.someNbr
FROM #table AS t
WHERE someNbr NOT LIKE '%[^0-9.]%';
The problem here is we'll also return "88.33.22" and miss "-29.33", both valid float values. You can handle hyphens by adding a hyphen to your LIKE pattern:
SELECT t.someNbr, LEN(t.SomeNbr)-LEN(REPLACE(t.SomeNbr,'.',''))
FROM #table AS t
WHERE someNbr NOT LIKE '%[^0-9.-]%';
But now we also pick up "9-9-" and stuff with 2+ dots. To ensure that each starts with a number OR a hyphen, to ensure hyphens only exist in the front of the string (if at all) and that we a maximum of one dot:
--==== This will do a good job but can still be broken
SELECT t.someNbr
FROM #table AS t
WHERE someNbr NOT LIKE '%[^0-9.-]%' -- Can only contain numbers, dots and hyphens
AND LEN(t.SomeNbr)-LEN(REPLACE(t.SomeNbr,'.','')) < 2 -- can have up to 1 dot
AND LEN(t.SomeNbr)-LEN(REPLACE(t.SomeNbr,'-','')) < 2 -- can have up to 1 hyphen
AND PATINDEX('%-%',t.SomeNbr) < 2 -- hyphen can only be in the front
This does the trick and returns:
someNbr
--------------------------------
0
0.12
999
-29.33
All that said - **DONT DO THIS ANY OF THIS ^^^ **. There is no need to parse numbers in this way except to show others why not to. I can still break this. They way I return valid floats in a scenario like this is with TRY_CAST or TRY_CONVERT. This returns what you need and will perform better.
--==== Best Solution
SELECT t.someNbr
FROM #table AS t
WHERE TRY_CAST(t.SomeNbr AS float) IS NOT NULL;

How to do a count of fields in SQL with wrong datatype

I am trying to import legacy data from another system into our system. The problem I am having is that the legacy data is dirty- very dirty! We have a field which should be an integer, but sometimes is a varchar, and the field is defined as a varchar...
In SQL Server, how can I do a select to show those records where the data is varchar instead if int?
Thanks
If you want to find rows1 where a column contains any non-digit characters or is longer than 9 characters (either condition means that we cannot assume it would fit in an int, use something like:
SELECT * FROM Table WHERE LEN(ColumnName) > 9 or ColumnName LIKE '%[^0-9]%'
Not that there's a negative in the LIKE condition - we're trying to find a string that contains at least one non-digit character.
A more modern approach would be to use TRY_CAST or TRY_CONVERT. But note that a failed conversion returns NULL and NULL is perfectly valid for an int!
SELECT * FROM Table WHERE ColumnName is not null and try_cast(ColumnName as int) is null
ISNUMERIC isn't appropriate. It answers a question nobody has ever wanted to ask (IMO) - "Can this string be converted to any of the numeric data types (I don't care which ones and I don't want you to tell me which ones either)?"
ISNUMERIC('$,,,,,,,.') is 1. That should tell you all you need to know about this function.
1If you just want a count, as per the title of the question, then substitute COUNT(*) for *.
In SQL Server, how can I do a select to show those records where the data is varchar instead of int?
I would do it like
CREATE TABLE T
(
Data VARCHAR(50)
);
INSERT INTO T VALUES
('102'),
(NULL),
('11Blah'),
('5'),
('Unknown'),
('1ThinkPad123'),
('-11');
SELECT Data -- Per the title COUNT(Data)
FROM
(
SELECT Data,
cast('' as xml).value('sql:column("Data") cast as xs:int ?','int') Result
FROM T --You can add WHERE Data IS NOT NULL to exclude NULLs
) TT
WHERE Result IS NULL;
Returns:
+----+--------------+
| | Data |
+----+--------------+
| 1 | NULL |
| 2 | 11Blah |
| 3 | Unknown |
| 4 | 1ThinkPad123 |
+----+--------------+
That if you can't use TRY_CAST() function, if you are working on 2012+ version, I'll recommend that you use TRY_CAST() function like
SELECT Data
FROM T
WHERE Data IS NOT NULL
AND
TRY_CAST(Data AS INT) IS NULL;
Demo
Finally, I would say do not use ISNUMERIC() function because of (from docs) ...
Note
ISNUMERIC returns 1 for some characters that are not numbers, such as plus (+), minus (-), and valid currency symbols such as the dollar sign ($). For a complete list of currency symbols, see money and smallmoney (Transact-SQL).

How to convert string to numbers (if numeric), otherwise leave as string in SQL

my column has customer numbers that are both numeric and combinations of text and numbers. I only want to convert them if they are all numeric otherwise leave them as a string
ex.
91036
ab321
10001
Only convert 91036 and 10001 as numbers (using cast or convert) but leave ab321 as string. I tried isnumeric but this isn't a recognized function in the query builder I'm using. And if I convert using cast or convert the strings are disappearing.
This is an example based on Oracle, but I believe that the same principle would work elsewhere (at least, in databases that support regular expressions).
I don't quite understand what you meant by saying that you want to "convert" those values to numbers; convert where? I presume that they are currently stored in a VARCHAR2 (or some other "character" datatype column). There's no use in converting them to number an leave them in the same column, as that wouldn't do absolutely anything - they would still be treated as strings (stored in the character datatype column, remember?).
So, I've created another - NUMBER datatype column and will populate it with a number whenever possible.
Sample data:
SQL> create table test (col_char varchar2(10),
2 col_num number);
Table created.
SQL> insert into test (col_char)
2 (select '91036' from dual union
3 select 'ab321' from dual union
4 select '10001' from dual
5 );
3 rows created.
Update uses REGEXP_LIKE function which checks whether COL_CHAR looks like a number:
^ anchors you to the beginning of the string
\d+ takes as many consecutive digits as it can find
$ anchors you to the end of the string
which, all together, means that string must begin with a digit, must end with a digit, and everything in between have to be digits.
SQL> update test set
2 col_num = to_number(col_char)
3 where regexp_like(col_char, '^\d+$');
2 rows updated.
SQL> select * From test;
COL_CHAR COL_NUM
---------- ----------
10001 10001
91036 91036
ab321
SQL>
Things are getting somewhat more complex when there are decimals and/or thousands separators in a string, so you might need to alter both TO_NUMBER function and regular expression pattern. For example:
SQL> update test set
2 col_num = to_number(col_char, '999990D00000', 'nls_numeric_characters = '',.''')
3 where regexp_like(col_char, '^[0-9]+|(\,)[0-9]+$');
2 rows updated.
SQL> select * from test;
COL_CHAR COL_NUM
---------- ----------
10001 10001
91,036 91,036
ab321
SQL>

Update column in postgresql

I found out that I have a character varaying column with mistakes in a database with over 4 millon records. It contains numbers. Each number has to have 12 digits, but for some reason a lot of those numbers ended up having 10 digits.
The good news is that the only thing I have to do, is prepend '55' to each cell that only has 10 digits and starts with the number '22', leaving the ones with 12 digits untouched.
My objective is this:
UPDATE
table
SET
column = CONCAT( '55', column )
WHERE
LENGTH( column ) = 10 AND column LIKE( '22%');
I am thinking of using this:
UPDATE
telephones
SET
telephone_number = CONCAT( '55', telephone_number )
WHERE
LENGTH( telephone_number ) = 10 AND telephone_number LIKE( '22%');
Am I doing it right? If not, what would be the correct way to do it
What if instead of a string the numbers were stored as big int, same rules apply, it is still 10 digits long which means the number is lower than 3.000.000.000 and bigger than 2.000.000.000? and they all need to be the same number starting with 55
The answer is: yes, that's right. You can play around with a sample database here on SQL Fiddle. That one uses the BIGINT type. Also see this one by #gmm, which uses the VARCHAR form. Both work just like you've described them using your original syntax.